cmicx_led.c (13102B)
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 * Purpose: CMICx led module 8 */ 9 #include <sal/core/boot.h> 10 #include <sal/core/libc.h> 11 #include <sal/core/sync.h> 12 #include <shared/alloc.h> 13 #include <shared/bsl.h> 14 15 #if defined (BCM_ESW_SUPPORT) || defined(BCM_DNXF_SUPPORT) || defined(BCM_DNX_SUPPORT) 16 #include <soc/drv.h> 17 #include <soc/cm.h> 18 #include <soc/cmic.h> 19 20 #ifdef BCM_CMICX_SUPPORT 21 #include <shared/cmicfw/iproc_mbox.h> 22 #include <shared/cmicfw/iproc_fwconfig.h> 23 #include <shared/cmicfw/cmicx_led.h> 24 25 /* 26 * Function: 27 * soc_cmicx_led_mbox_init 28 * Purpose: 29 * Initialize LED MBOX structure. 30 * Parameters: 31 * unit number 32 * Returns: 33 * SOC_E_xxx 34 */ 35 int soc_cmicx_led_mbox_init(int unit) 36 { 37 int rv = SOC_E_NONE; 38 soc_control_t *soc = SOC_CONTROL(unit); 39 40 if(!SOC_CONTROL(unit)->iproc_m0led_init_done) { 41 SOC_IF_ERROR_RETURN(SOC_CONTROL(unit)->led_mbox_id = soc_iproc_mbox_alloc(unit, U0_LED_APP)); 42 SOC_CONTROL(unit)->led_txmbox= &soc->iproc_mbox_info[SOC_CONTROL(unit)->led_mbox_id][IPROC_MBOX_TYPE_TX]; 43 SOC_CONTROL(unit)->led_rxmbox= &soc->iproc_mbox_info[SOC_CONTROL(unit)->led_mbox_id][IPROC_MBOX_TYPE_RX]; 44 SOC_CONTROL(unit)->iproc_m0led_init_done = 1; 45 } 46 47 return rv; 48 } 49 50 /* 51 * Function: 52 * soc_cmicx_led_deinit 53 * Purpose: 54 * Cleanup led mbox and handler. 55 * Parameters: 56 * unit number 57 * Returns: 58 * SOC_E_xxx 59 */ 60 int soc_cmicx_led_deinit(int unit) 61 { 62 int rv = 0; 63 64 if (SOC_CONTROL(unit)->iproc_m0led_init_done) { 65 soc_iproc_mbox_free(unit, SOC_CONTROL(unit)->led_mbox_id); 66 SOC_CONTROL(unit)->iproc_m0led_init_done = 0; 67 } 68 69 return rv; 70 } 71 72 73 74 /* 75 * Function: 76 * soc_cmicx_led_link_status 77 * Purpose: 78 * Send LED_MSG_LNK_STS message to Cortex-M0 led application. 79 * Parameters: 80 * unit number 81 * link_status -- link status for each port 82 * Returns: 83 * SOC_E_xxx 84 */ 85 int soc_cmicx_led_link_status(int unit, soc_led_link_status_t *link_status) 86 { 87 int rv = SOC_E_NONE; 88 soc_iproc_mbox_msg_t *msg, *resp; 89 90 if(!SOC_CONTROL(unit)->iproc_m0led_init_done) { 91 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Init not done\n"))); 92 return SOC_E_FAIL; 93 } 94 95 msg = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(soc_led_link_status_t)); 96 if (msg == NULL) { 97 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox msg alloc failed\n"))); 98 return SOC_E_MEMORY; 99 } 100 101 resp = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(soc_led_link_status_t)); 102 if (resp == NULL) { 103 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox resp alloc failed\n"))); 104 soc_iproc_free(msg); 105 return SOC_E_MEMORY; 106 } 107 108 /* 109 * For DNX, port is passed as physical port that is 0 base, 110 * but the port was taken as 1 base by M0 led app. 111 * So tune it here. 112 */ 113 if (SOC_IS_DNX(unit)) 114 { 115 link_status->port += 1; 116 } 117 118 /* Prepare the message */ 119 msg->id = LED_MSG_LNK_STS; 120 msg->flags = IPROC_SYNC_MSG | IPROC_RESP_REQUIRED; 121 msg->size = sizeof(soc_led_link_status_t) / sizeof(uint32); 122 if (sizeof(soc_led_link_status_t) % sizeof(uint32)) { 123 msg->size++; 124 } 125 126 /* Copy message data */ 127 sal_memcpy((void *)msg->data, (void *)link_status, sizeof(soc_led_link_status_t)); 128 129 rv = soc_iproc_data_send_wait(SOC_CONTROL(unit)->led_txmbox, msg, resp); 130 if (rv == IPROC_MSG_SUCCESS) { 131 if (IS_IPROC_RESP_READY(resp)) { 132 if (IS_IPROC_RESP_SUCCESS(resp)) { 133 rv = SOC_E_NONE; 134 } 135 else { 136 rv = resp->data[0]; 137 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 138 "Led msg id 0x%x failed, Error Code %d\n"), msg->id, rv)); 139 } 140 } 141 } else { 142 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 143 "Led msg id 0x%x send failed, Error Code %d\n"), msg->id, rv)); 144 } 145 soc_iproc_free(msg); 146 soc_iproc_free(resp); 147 return rv; 148 } 149 150 /* 151 * Function: 152 * soc_cmicx_led_status_get 153 * Purpose: 154 * Send LED_MSG_STATUS message to Cortex-M0 led application. 155 * Parameters: 156 * unit number 157 * led_port_status -- get status for the given port 158 * Returns: 159 * SOC_E_xxx 160 */ 161 int soc_cmicx_led_status_get(int unit, soc_led_port_status_t *led_port_status) 162 { 163 int rv = SOC_E_NONE; 164 soc_iproc_mbox_msg_t *msg, *resp; 165 166 if(!SOC_CONTROL(unit)->iproc_m0led_init_done) { 167 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Init not done\n"))); 168 return SOC_E_FAIL; 169 } 170 171 msg = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(soc_led_port_status_t)); 172 if (msg == NULL) { 173 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox msg alloc failed\n"))); 174 return SOC_E_MEMORY; 175 } 176 177 resp = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(soc_led_port_status_t)); 178 if (resp == NULL) { 179 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox resp alloc failed\n"))); 180 soc_iproc_free(msg); 181 return SOC_E_MEMORY; 182 } 183 /* 184 * For DNX, port is passed as physical port that is 0 base, 185 * but the port was taken as 1 base by M0 led app. 186 * So tune it here. 187 */ 188 if (SOC_IS_DNX(unit)) 189 { 190 led_port_status->port += 1; 191 } 192 193 /* Prepare the message */ 194 msg->id = LED_MSG_STATUS; 195 msg->flags = IPROC_SYNC_MSG | IPROC_RESP_REQUIRED; 196 msg->size = sizeof(soc_led_port_status_t) / sizeof(uint32); 197 if (sizeof(soc_led_port_status_t) % sizeof(uint32)) { 198 msg->size++; 199 } 200 201 /* Copy message data */ 202 sal_memcpy((void *)msg->data, (void *)led_port_status, sizeof(soc_led_port_status_t)); 203 204 rv = soc_iproc_data_send_wait(SOC_CONTROL(unit)->led_txmbox, msg, resp); 205 if (rv == IPROC_MSG_SUCCESS) { 206 if (IS_IPROC_RESP_READY(resp)) { 207 if (IS_IPROC_RESP_SUCCESS(resp)) { 208 /* get the status */ 209 led_port_status->status = resp->data[0]; 210 rv = SOC_E_NONE; 211 } 212 else { 213 rv = resp->data[0]; 214 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 215 "Led msg id 0x%x failed, Error Code %d\n"), msg->id, rv)); 216 } 217 } 218 } else { 219 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 220 "Led msg id 0x%x send failed, Error Code %d\n"), msg->id, rv)); 221 } 222 soc_iproc_free(msg); 223 soc_iproc_free(resp); 224 return rv; 225 } 226 227 /* 228 * Function: 229 * soc_cmicx_led_status_set 230 * Purpose: 231 * Send LED_MSG_STATUS_SET message to Cortex-M0 led application. 232 * Parameters: 233 * unit number 234 * led_port_status -- status to be set for the given port 235 * Returns: 236 * SOC_E_xxx 237 */ 238 int soc_cmicx_led_status_set(int unit, soc_led_port_status_t *led_port_status) 239 { 240 int rv = SOC_E_NONE; 241 soc_iproc_mbox_msg_t *msg, *resp; 242 243 if(!SOC_CONTROL(unit)->iproc_m0led_init_done) { 244 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Init not done\n"))); 245 return SOC_E_FAIL; 246 } 247 248 msg = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(soc_led_port_status_t)); 249 if (msg == NULL) { 250 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox msg alloc failed\n"))); 251 return SOC_E_MEMORY; 252 } 253 254 resp = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(soc_led_port_status_t)); 255 if (resp == NULL) { 256 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox resp alloc failed\n"))); 257 soc_iproc_free(msg); 258 return SOC_E_MEMORY; 259 } 260 /* 261 * For DNX, port is passed as physical port that is 0 base, 262 * but the port was taken as 1 base by M0 led app. 263 * So tune it here. 264 */ 265 if (SOC_IS_DNX(unit)) 266 { 267 led_port_status->port += 1; 268 } 269 270 /* Prepare the message */ 271 msg->id = LED_MSG_STATUS_SET; 272 msg->flags = IPROC_SYNC_MSG | IPROC_RESP_REQUIRED; 273 msg->size = sizeof(soc_led_port_status_t) / sizeof(uint32); 274 if (sizeof(soc_led_port_status_t) % sizeof(uint32)) { 275 msg->size++; 276 } 277 278 /* Copy message data */ 279 sal_memcpy((void *)msg->data, (void *)led_port_status, sizeof(soc_led_port_status_t)); 280 281 rv = soc_iproc_data_send_wait(SOC_CONTROL(unit)->led_txmbox, msg, resp); 282 if (rv == IPROC_MSG_SUCCESS) { 283 if (IS_IPROC_RESP_READY(resp)) { 284 if (IS_IPROC_RESP_SUCCESS(resp)) { 285 rv = SOC_E_NONE; 286 } 287 else { 288 rv = resp->data[0]; 289 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 290 "Led msg id 0x%x failed, Error Code %d\n"), msg->id, rv)); 291 } 292 } 293 } else { 294 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 295 "Led msg id 0x%x send failed, Error Code %d\n"), msg->id, rv)); 296 } 297 soc_iproc_free(msg); 298 soc_iproc_free(resp); 299 return rv; 300 } 301 302 /* 303 * Function: 304 * soc_cmicx_led_enable 305 * Purpose: 306 * Send LED_MSG_ENABLE message to Cortex-M0 led application. 307 * Parameters: 308 * unit number 309 * enable -- enable/disable the led fw 310 * Returns: 311 * SOC_E_xxx 312 */ 313 int soc_cmicx_led_enable(int unit, uint32 enable) 314 { 315 int rv = SOC_E_NONE; 316 soc_iproc_mbox_msg_t *msg, *resp; 317 soc_control_t *soc = SOC_CONTROL(unit); 318 319 if (!SOC_CONTROL(unit)->iproc_m0led_init_done) { 320 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "LED init not done..skipping %s!\n"), enable ? "start" : "stop")); 321 return SOC_E_NONE; 322 } 323 324 msg = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(uint32)); 325 if (msg == NULL) { 326 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox msg alloc failed\n"))); 327 return SOC_E_MEMORY; 328 } 329 330 resp = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(uint32)); 331 if (resp == NULL) { 332 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox resp alloc failed\n"))); 333 soc_iproc_free(msg); 334 return SOC_E_MEMORY; 335 } 336 337 /* Prepare the message */ 338 msg->id = LED_MSG_ENABLE; 339 msg->flags = IPROC_SYNC_MSG | IPROC_RESP_REQUIRED; 340 msg->size = 1; 341 msg->data[0] = enable; 342 343 rv = soc_iproc_data_send_wait(SOC_CONTROL(unit)->led_txmbox, msg, resp); 344 if (rv == IPROC_MSG_SUCCESS) { 345 if (IS_IPROC_RESP_READY(resp)) { 346 if (IS_IPROC_RESP_SUCCESS(resp)) { 347 rv = SOC_E_NONE; 348 soc->led_fw_enabled = enable; 349 } 350 else { 351 rv = resp->data[0]; 352 } 353 } 354 } else { 355 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 356 "Led msg id 0x%x send failed, Error Code %d\n"), msg->id, rv)); 357 } 358 soc_iproc_free(msg); 359 soc_iproc_free(resp); 360 return rv; 361 } 362 363 /* 364 * Function: 365 * soc_cmicx_led_speed 366 * Purpose: 367 * Send LED_MSG_SPEED message to Cortex-M0 led application. 368 * Parameters: 369 * unit number 370 * led_port_speed -- speed for the given port 371 * Returns: 372 * SOC_E_xxx 373 */ 374 int soc_cmicx_led_speed(int unit, soc_led_port_speed_t *led_port_speed) 375 { 376 int rv = SOC_E_NONE; 377 soc_iproc_mbox_msg_t *msg, *resp; 378 379 if(!SOC_CONTROL(unit)->iproc_m0led_init_done) { 380 LOG_VERBOSE(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Init not done\n"))); 381 return SOC_E_FAIL; 382 } 383 384 msg = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(soc_led_port_status_t)); 385 if (msg == NULL) { 386 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox msg alloc failed\n"))); 387 return SOC_E_MEMORY; 388 } 389 390 resp = soc_iproc_alloc(sizeof(soc_iproc_mbox_msg_t) + sizeof(soc_led_port_status_t)); 391 if (resp == NULL) { 392 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, "Led Mbox resp alloc failed\n"))); 393 soc_iproc_free(msg); 394 return SOC_E_MEMORY; 395 } 396 397 /* Prepare the message */ 398 msg->id = LED_MSG_SPEED; 399 msg->flags = IPROC_SYNC_MSG | IPROC_RESP_REQUIRED; 400 msg->size = sizeof(soc_led_port_speed_t) / sizeof(uint32); 401 if (sizeof(soc_led_port_speed_t) % sizeof(uint32)) { 402 msg->size++; 403 } 404 405 /* Copy message data */ 406 sal_memcpy((void *)msg->data, (void *)led_port_speed, sizeof(soc_led_port_speed_t)); 407 408 rv = soc_iproc_data_send_wait(SOC_CONTROL(unit)->led_txmbox, msg, resp); 409 if (rv == IPROC_MSG_SUCCESS) { 410 if (IS_IPROC_RESP_READY(resp)) { 411 if (IS_IPROC_RESP_SUCCESS(resp)) { 412 rv = SOC_E_NONE; 413 } 414 else { 415 rv = resp->data[0]; 416 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 417 "Led msg id 0x%x failed, Error Code %d\n"), msg->id, rv)); 418 } 419 } 420 } else { 421 LOG_ERROR(BSL_LS_SOC_COMMON, (BSL_META_U(unit, 422 "Led msg id 0x%x send failed, Error Code %d\n"), msg->id, rv)); 423 } 424 soc_iproc_free(msg); 425 soc_iproc_free(resp); 426 return rv; 427 } 428 429 #endif /*BCM_CMICX_SUPPORT*/ 430 #endif /*BCM_ESW_SUPPORT*/