diff --git a/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/Makefile b/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/Makefile index e5b384c08..a9c93b1dd 100644 --- a/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/Makefile +++ b/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/Makefile @@ -1,5 +1,6 @@ KERNELS := onl-kernel-6.12-lts-x86-64-all:amd64 -KMODULES := src +KINCLUDES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h +KMODULES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c $(wildcard src/*.c) VENDOR := accton BASENAME := x86-64-accton-as7535-28xb ARCH := x86_64 diff --git a/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/src/Makefile b/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/src/Makefile deleted file mode 100644 index 33f88fb0a..000000000 --- a/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/src/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -obj-m += accton_ipmi_intf.o -obj-m += x86-64-accton-as7535-28xb-cpld.o -obj-m += x86-64-accton-as7535-28xb-fan.o -obj-m += x86-64-accton-as7535-28xb-fpga.o -obj-m += x86-64-accton-as7535-28xb-leds.o -obj-m += x86-64-accton-as7535-28xb-psu.o -obj-m += x86-64-accton-as7535-28xb-sys.o -obj-m += x86-64-accton-as7535-28xb-thermal.o \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/src/accton_ipmi_intf.h b/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/src/accton_ipmi_intf.h deleted file mode 100644 index 4b2fe59f9..000000000 --- a/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/src/accton_ipmi_intf.h +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface declarations - */ - -#ifndef ACCTON_IPMI_INTF_H -#define ACCTON_IPMI_INTF_H - -#include -#include - -/* Structure to hold IPMI (Intelligent Platform Management Interface) data */ -struct ipmi_data { - struct completion read_complete; // Synchronization primitive for signaling message read completion - struct ipmi_addr address; // Structure to store the IPMI system interface address - struct ipmi_user *user; // Pointer to IPMI user created by the kernel - int interface; // Interface identifier for the IPMI system - - struct kernel_ipmi_msg tx_message; // Message structure for sending IPMI commands - long tx_msgid; // Message ID for tracking IPMI message transactions - - void *rx_msg_data; // Pointer to buffer for storing received IPMI message data - unsigned short rx_msg_len; // Length of the received IPMI message - unsigned char rx_result; // Result code from the received IPMI message - int rx_recv_type; // Type of the received message (e.g., system interface, LAN, etc.) - - struct ipmi_user_hndl ipmi_hndlrs; // IPMI handler structure for handling incoming IPMI messages - struct device *dev; // Device structure for logging errors -}; - -/* Function declarations */ - -/* - * Initialize IPMI data structure and create a user interface for communication. - * - * @param ipmi: Pointer to ipmi_data structure to be initialized. - * @param iface: IPMI interface identifier. - * @param dev: Device structure for logging errors. - * @return 0 on success, or an error code on failure. - */ -extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev); - -/* - * Send an IPMI command to the IPMI device and receive the response. - * - * @param ipmi: Pointer to ipmi_data structure containing IPMI communication information. - * @param cmd: IPMI command byte. - * @param tx_data: Pointer to data buffer for the command payload. - * @param tx_len: Length of the command payload data. - * @param rx_data: Pointer to buffer for storing the response data. - * @param rx_len: Length of the response data buffer. - * @return 0 on success, or an error code on failure. - */ -extern int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len); - -#endif /* ACCTON_IPMI_INTF_H */ diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/Makefile b/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/Makefile index 95c6ba395..d8ae35b6f 100644 --- a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/Makefile +++ b/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/Makefile @@ -1,5 +1,6 @@ KERNELS := onl-kernel-6.12-lts-x86-64-all:amd64 -KMODULES := src +KINCLUDES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h +KMODULES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c $(wildcard src/*.c) VENDOR := accton BASENAME := x86-64-accton-as7926-40xfb ARCH := x86_64 diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/Makefile b/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/Makefile deleted file mode 100644 index 83c060968..000000000 --- a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -obj-m += accton_ipmi_intf.o -obj-m += x86-64-accton-as7926-40xfb-cpld.o -obj-m += x86-64-accton-as7926-40xfb-fan.o -obj-m += x86-64-accton-as7926-40xfb-leds.o -obj-m += x86-64-accton-as7926-40xfb-psu.o -obj-m += x86-64-accton-as7926-40xfb-sys.o -obj-m += x86-64-accton-as7926-40xfb-thermal.o \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/accton_ipmi_intf.c b/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/accton_ipmi_intf.c deleted file mode 100644 index 48a0c9acf..000000000 --- a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/accton_ipmi_intf.c +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface implementation - */ -#include -#include -#include -#include "accton_ipmi_intf.h" - -#define ACCTON_IPMI_NETFN 0x34 -#define IPMI_TIMEOUT (5 * HZ) -#define IPMI_ERR_RETRY_TIMES 1 -#define RAW_CMD_BUF_SIZE 40 - -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); - -/* Functions to talk to the IPMI layer */ - -/* Initialize IPMI data structure and create a user interface for communication */ -int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev) -{ - int err; - - if (!ipmi || !dev) - return -EINVAL; - - init_completion(&ipmi->read_complete); - - // Initialize IPMI address - ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - ipmi->address.channel = IPMI_BMC_CHANNEL; - ipmi->address.data[0] = 0; - ipmi->interface = iface; - ipmi->dev = dev; // Storing the device for future reference - - // Initialize message buffers - ipmi->tx_msgid = 0; - ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; - - // Assign the message handler - ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; - - // Create IPMI messaging interface user - err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, - ipmi, &ipmi->user); - if (err < 0) { - dev_err(dev, - "Unable to register user with IPMI interface %d, err: %d\n", - ipmi->interface, err); - return err; - } - - return 0; -} -EXPORT_SYMBOL(init_ipmi_data); - -/* Handler function for receiving IPMI messages */ -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) -{ - unsigned short rx_len; - struct ipmi_data *ipmi = user_msg_data; - - // Check for message ID mismatch - if (msg->msgid != ipmi->tx_msgid) { - dev_err(ipmi->dev, "Mismatch between received msgid " - "(%02x) and transmitted msgid (%02x)!\n", - (int)msg->msgid, (int)ipmi->tx_msgid); - ipmi_free_recv_msg(msg); - return; - } - - // Handle received message type - ipmi->rx_recv_type = msg->recv_type; - - // Parse message data - if (msg->msg.data_len > 0) - ipmi->rx_result = msg->msg.data[0]; - else - ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; - - // Copy remaining message data if available - if (msg->msg.data_len > 1) { - rx_len = msg->msg.data_len - 1; - if (ipmi->rx_msg_len < rx_len) - rx_len = ipmi->rx_msg_len; - - ipmi->rx_msg_len = rx_len; - memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); - } else { - ipmi->rx_msg_len = 0; - } - - // Free the received message and signal completion - ipmi_free_recv_msg(msg); - complete(&ipmi->read_complete); -} - -static void _ipmi_log_error(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - int status, int retry) -{ - int i, pos; - char *cmdline = NULL; - char raw_cmd[RAW_CMD_BUF_SIZE] = { 0 }; - - // Format the command and data into a raw command string - pos = snprintf(raw_cmd, sizeof(raw_cmd), "0x%02x", cmd); - for (i = 0; i < tx_len && pos < sizeof(raw_cmd); i++) { - pos += snprintf(raw_cmd + pos, sizeof(raw_cmd) - pos, - " 0x%02x", tx_data[i]); - } - - // Log the error message - cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); - dev_err(ipmi->dev, - "ipmi_send_message: retry(%d), error(%d), cmd(%s) raw_cmd=[%s]\r\n", - retry, status, cmdline ? cmdline : "", raw_cmd); - - if (cmdline) { - kfree(cmdline); - } -} - -/* Send an IPMI command */ -static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int err; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - // Initialize IPMI message - ipmi->tx_message.cmd = cmd; - ipmi->tx_message.data = tx_len ? tx_data : NULL; - ipmi->tx_message.data_len = tx_len; - ipmi->rx_msg_data = rx_len ? rx_data : NULL; - ipmi->rx_msg_len = rx_len; - - // Validate the IPMI address - err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); - if (err) { - dev_err(ipmi->dev, "Invalid IPMI address: %x\n", err); - return err; - } - - // Increment message ID and send the request - ipmi->tx_msgid++; - err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, - &ipmi->tx_message, ipmi, 0, 0, 0); - if (err) { - dev_err(ipmi->dev, "IPMI request_settime failed: %x\n", err); - return err; - } - - // Wait for the message to complete - err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!err) { - dev_err(ipmi->dev, "IPMI command timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - -/* Send an IPMI command to the IPMI device and receive the response */ -int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int status = 0, retry = 0; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { - status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len); - if (unlikely(status != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - if (unlikely(ipmi->rx_result != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - // Success, exit the retry loop - break; - } - - return status; -} - -EXPORT_SYMBOL(ipmi_send_message); - -static int __init ipmi_module_init(void) -{ - printk(KERN_INFO "Accton IPMI Module loaded\n"); - return 0; -} - -static void __exit ipmi_module_exit(void) -{ - printk(KERN_INFO "Accton IPMI Module unloaded\n"); -} - -module_init(ipmi_module_init); -module_exit(ipmi_module_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("Accton IPMI messaging module"); -MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/Makefile b/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/Makefile index 454dba276..784df8914 100644 --- a/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/Makefile +++ b/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/Makefile @@ -1,5 +1,6 @@ KERNELS := onl-kernel-6.12-lts-x86-64-all:amd64 -KMODULES := src +KINCLUDES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h +KMODULES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c $(wildcard src/*.c) VENDOR := accton BASENAME := x86-64-accton-as7946-30xb ARCH := x86_64 diff --git a/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/Makefile b/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/Makefile deleted file mode 100644 index eba297ac1..000000000 --- a/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -obj-m += accton_ipmi_intf.o -obj-m += x86-64-accton-as7946-30xb-cpld.o -obj-m += x86-64-accton-as7946-30xb-fan.o -obj-m += x86-64-accton-as7946-30xb-leds.o -obj-m += x86-64-accton-as7946-30xb-psu.o -obj-m += x86-64-accton-as7946-30xb-sys.o -obj-m += x86-64-accton-as7946-30xb-thermal.o \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/accton_ipmi_intf.c b/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/accton_ipmi_intf.c deleted file mode 100644 index 48a0c9acf..000000000 --- a/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/accton_ipmi_intf.c +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface implementation - */ -#include -#include -#include -#include "accton_ipmi_intf.h" - -#define ACCTON_IPMI_NETFN 0x34 -#define IPMI_TIMEOUT (5 * HZ) -#define IPMI_ERR_RETRY_TIMES 1 -#define RAW_CMD_BUF_SIZE 40 - -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); - -/* Functions to talk to the IPMI layer */ - -/* Initialize IPMI data structure and create a user interface for communication */ -int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev) -{ - int err; - - if (!ipmi || !dev) - return -EINVAL; - - init_completion(&ipmi->read_complete); - - // Initialize IPMI address - ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - ipmi->address.channel = IPMI_BMC_CHANNEL; - ipmi->address.data[0] = 0; - ipmi->interface = iface; - ipmi->dev = dev; // Storing the device for future reference - - // Initialize message buffers - ipmi->tx_msgid = 0; - ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; - - // Assign the message handler - ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; - - // Create IPMI messaging interface user - err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, - ipmi, &ipmi->user); - if (err < 0) { - dev_err(dev, - "Unable to register user with IPMI interface %d, err: %d\n", - ipmi->interface, err); - return err; - } - - return 0; -} -EXPORT_SYMBOL(init_ipmi_data); - -/* Handler function for receiving IPMI messages */ -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) -{ - unsigned short rx_len; - struct ipmi_data *ipmi = user_msg_data; - - // Check for message ID mismatch - if (msg->msgid != ipmi->tx_msgid) { - dev_err(ipmi->dev, "Mismatch between received msgid " - "(%02x) and transmitted msgid (%02x)!\n", - (int)msg->msgid, (int)ipmi->tx_msgid); - ipmi_free_recv_msg(msg); - return; - } - - // Handle received message type - ipmi->rx_recv_type = msg->recv_type; - - // Parse message data - if (msg->msg.data_len > 0) - ipmi->rx_result = msg->msg.data[0]; - else - ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; - - // Copy remaining message data if available - if (msg->msg.data_len > 1) { - rx_len = msg->msg.data_len - 1; - if (ipmi->rx_msg_len < rx_len) - rx_len = ipmi->rx_msg_len; - - ipmi->rx_msg_len = rx_len; - memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); - } else { - ipmi->rx_msg_len = 0; - } - - // Free the received message and signal completion - ipmi_free_recv_msg(msg); - complete(&ipmi->read_complete); -} - -static void _ipmi_log_error(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - int status, int retry) -{ - int i, pos; - char *cmdline = NULL; - char raw_cmd[RAW_CMD_BUF_SIZE] = { 0 }; - - // Format the command and data into a raw command string - pos = snprintf(raw_cmd, sizeof(raw_cmd), "0x%02x", cmd); - for (i = 0; i < tx_len && pos < sizeof(raw_cmd); i++) { - pos += snprintf(raw_cmd + pos, sizeof(raw_cmd) - pos, - " 0x%02x", tx_data[i]); - } - - // Log the error message - cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); - dev_err(ipmi->dev, - "ipmi_send_message: retry(%d), error(%d), cmd(%s) raw_cmd=[%s]\r\n", - retry, status, cmdline ? cmdline : "", raw_cmd); - - if (cmdline) { - kfree(cmdline); - } -} - -/* Send an IPMI command */ -static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int err; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - // Initialize IPMI message - ipmi->tx_message.cmd = cmd; - ipmi->tx_message.data = tx_len ? tx_data : NULL; - ipmi->tx_message.data_len = tx_len; - ipmi->rx_msg_data = rx_len ? rx_data : NULL; - ipmi->rx_msg_len = rx_len; - - // Validate the IPMI address - err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); - if (err) { - dev_err(ipmi->dev, "Invalid IPMI address: %x\n", err); - return err; - } - - // Increment message ID and send the request - ipmi->tx_msgid++; - err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, - &ipmi->tx_message, ipmi, 0, 0, 0); - if (err) { - dev_err(ipmi->dev, "IPMI request_settime failed: %x\n", err); - return err; - } - - // Wait for the message to complete - err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!err) { - dev_err(ipmi->dev, "IPMI command timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - -/* Send an IPMI command to the IPMI device and receive the response */ -int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int status = 0, retry = 0; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { - status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len); - if (unlikely(status != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - if (unlikely(ipmi->rx_result != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - // Success, exit the retry loop - break; - } - - return status; -} - -EXPORT_SYMBOL(ipmi_send_message); - -static int __init ipmi_module_init(void) -{ - printk(KERN_INFO "Accton IPMI Module loaded\n"); - return 0; -} - -static void __exit ipmi_module_exit(void) -{ - printk(KERN_INFO "Accton IPMI Module unloaded\n"); -} - -module_init(ipmi_module_init); -module_exit(ipmi_module_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("Accton IPMI messaging module"); -MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/accton_ipmi_intf.h b/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/accton_ipmi_intf.h deleted file mode 100644 index 4b2fe59f9..000000000 --- a/packages/platforms/accton/x86-64/as7946-30xb/modules/builds/src/accton_ipmi_intf.h +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface declarations - */ - -#ifndef ACCTON_IPMI_INTF_H -#define ACCTON_IPMI_INTF_H - -#include -#include - -/* Structure to hold IPMI (Intelligent Platform Management Interface) data */ -struct ipmi_data { - struct completion read_complete; // Synchronization primitive for signaling message read completion - struct ipmi_addr address; // Structure to store the IPMI system interface address - struct ipmi_user *user; // Pointer to IPMI user created by the kernel - int interface; // Interface identifier for the IPMI system - - struct kernel_ipmi_msg tx_message; // Message structure for sending IPMI commands - long tx_msgid; // Message ID for tracking IPMI message transactions - - void *rx_msg_data; // Pointer to buffer for storing received IPMI message data - unsigned short rx_msg_len; // Length of the received IPMI message - unsigned char rx_result; // Result code from the received IPMI message - int rx_recv_type; // Type of the received message (e.g., system interface, LAN, etc.) - - struct ipmi_user_hndl ipmi_hndlrs; // IPMI handler structure for handling incoming IPMI messages - struct device *dev; // Device structure for logging errors -}; - -/* Function declarations */ - -/* - * Initialize IPMI data structure and create a user interface for communication. - * - * @param ipmi: Pointer to ipmi_data structure to be initialized. - * @param iface: IPMI interface identifier. - * @param dev: Device structure for logging errors. - * @return 0 on success, or an error code on failure. - */ -extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev); - -/* - * Send an IPMI command to the IPMI device and receive the response. - * - * @param ipmi: Pointer to ipmi_data structure containing IPMI communication information. - * @param cmd: IPMI command byte. - * @param tx_data: Pointer to data buffer for the command payload. - * @param tx_len: Length of the command payload data. - * @param rx_data: Pointer to buffer for storing the response data. - * @param rx_len: Length of the response data buffer. - * @return 0 on success, or an error code on failure. - */ -extern int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len); - -#endif /* ACCTON_IPMI_INTF_H */ diff --git a/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/Makefile b/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/Makefile index 6079a483f..86a13b1d1 100644 --- a/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/Makefile +++ b/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/Makefile @@ -1,5 +1,6 @@ KERNELS := onl-kernel-6.12-lts-x86-64-all:amd64 -KMODULES := src +KINCLUDES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h +KMODULES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c $(wildcard src/*.c) VENDOR := accton BASENAME := x86-64-accton-as7946-74xkb ARCH := x86_64 diff --git a/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/Makefile b/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/Makefile deleted file mode 100644 index 2bc8c322a..000000000 --- a/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -obj-m += accton_ipmi_intf.o -obj-m += x86-64-accton-as7946-74xkb-cpld.o -obj-m += x86-64-accton-as7946-74xkb-fan.o -obj-m += x86-64-accton-as7946-74xkb-leds.o -obj-m += x86-64-accton-as7946-74xkb-psu.o -obj-m += x86-64-accton-as7946-74xkb-sys.o -obj-m += x86-64-accton-as7946-74xkb-thermal.o \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/accton_ipmi_intf.c b/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/accton_ipmi_intf.c deleted file mode 100644 index 48a0c9acf..000000000 --- a/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/accton_ipmi_intf.c +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface implementation - */ -#include -#include -#include -#include "accton_ipmi_intf.h" - -#define ACCTON_IPMI_NETFN 0x34 -#define IPMI_TIMEOUT (5 * HZ) -#define IPMI_ERR_RETRY_TIMES 1 -#define RAW_CMD_BUF_SIZE 40 - -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); - -/* Functions to talk to the IPMI layer */ - -/* Initialize IPMI data structure and create a user interface for communication */ -int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev) -{ - int err; - - if (!ipmi || !dev) - return -EINVAL; - - init_completion(&ipmi->read_complete); - - // Initialize IPMI address - ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - ipmi->address.channel = IPMI_BMC_CHANNEL; - ipmi->address.data[0] = 0; - ipmi->interface = iface; - ipmi->dev = dev; // Storing the device for future reference - - // Initialize message buffers - ipmi->tx_msgid = 0; - ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; - - // Assign the message handler - ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; - - // Create IPMI messaging interface user - err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, - ipmi, &ipmi->user); - if (err < 0) { - dev_err(dev, - "Unable to register user with IPMI interface %d, err: %d\n", - ipmi->interface, err); - return err; - } - - return 0; -} -EXPORT_SYMBOL(init_ipmi_data); - -/* Handler function for receiving IPMI messages */ -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) -{ - unsigned short rx_len; - struct ipmi_data *ipmi = user_msg_data; - - // Check for message ID mismatch - if (msg->msgid != ipmi->tx_msgid) { - dev_err(ipmi->dev, "Mismatch between received msgid " - "(%02x) and transmitted msgid (%02x)!\n", - (int)msg->msgid, (int)ipmi->tx_msgid); - ipmi_free_recv_msg(msg); - return; - } - - // Handle received message type - ipmi->rx_recv_type = msg->recv_type; - - // Parse message data - if (msg->msg.data_len > 0) - ipmi->rx_result = msg->msg.data[0]; - else - ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; - - // Copy remaining message data if available - if (msg->msg.data_len > 1) { - rx_len = msg->msg.data_len - 1; - if (ipmi->rx_msg_len < rx_len) - rx_len = ipmi->rx_msg_len; - - ipmi->rx_msg_len = rx_len; - memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); - } else { - ipmi->rx_msg_len = 0; - } - - // Free the received message and signal completion - ipmi_free_recv_msg(msg); - complete(&ipmi->read_complete); -} - -static void _ipmi_log_error(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - int status, int retry) -{ - int i, pos; - char *cmdline = NULL; - char raw_cmd[RAW_CMD_BUF_SIZE] = { 0 }; - - // Format the command and data into a raw command string - pos = snprintf(raw_cmd, sizeof(raw_cmd), "0x%02x", cmd); - for (i = 0; i < tx_len && pos < sizeof(raw_cmd); i++) { - pos += snprintf(raw_cmd + pos, sizeof(raw_cmd) - pos, - " 0x%02x", tx_data[i]); - } - - // Log the error message - cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); - dev_err(ipmi->dev, - "ipmi_send_message: retry(%d), error(%d), cmd(%s) raw_cmd=[%s]\r\n", - retry, status, cmdline ? cmdline : "", raw_cmd); - - if (cmdline) { - kfree(cmdline); - } -} - -/* Send an IPMI command */ -static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int err; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - // Initialize IPMI message - ipmi->tx_message.cmd = cmd; - ipmi->tx_message.data = tx_len ? tx_data : NULL; - ipmi->tx_message.data_len = tx_len; - ipmi->rx_msg_data = rx_len ? rx_data : NULL; - ipmi->rx_msg_len = rx_len; - - // Validate the IPMI address - err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); - if (err) { - dev_err(ipmi->dev, "Invalid IPMI address: %x\n", err); - return err; - } - - // Increment message ID and send the request - ipmi->tx_msgid++; - err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, - &ipmi->tx_message, ipmi, 0, 0, 0); - if (err) { - dev_err(ipmi->dev, "IPMI request_settime failed: %x\n", err); - return err; - } - - // Wait for the message to complete - err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!err) { - dev_err(ipmi->dev, "IPMI command timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - -/* Send an IPMI command to the IPMI device and receive the response */ -int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int status = 0, retry = 0; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { - status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len); - if (unlikely(status != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - if (unlikely(ipmi->rx_result != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - // Success, exit the retry loop - break; - } - - return status; -} - -EXPORT_SYMBOL(ipmi_send_message); - -static int __init ipmi_module_init(void) -{ - printk(KERN_INFO "Accton IPMI Module loaded\n"); - return 0; -} - -static void __exit ipmi_module_exit(void) -{ - printk(KERN_INFO "Accton IPMI Module unloaded\n"); -} - -module_init(ipmi_module_init); -module_exit(ipmi_module_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("Accton IPMI messaging module"); -MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/accton_ipmi_intf.h b/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/accton_ipmi_intf.h deleted file mode 100644 index 4b2fe59f9..000000000 --- a/packages/platforms/accton/x86-64/as7946-74xkb/modules/builds/src/accton_ipmi_intf.h +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface declarations - */ - -#ifndef ACCTON_IPMI_INTF_H -#define ACCTON_IPMI_INTF_H - -#include -#include - -/* Structure to hold IPMI (Intelligent Platform Management Interface) data */ -struct ipmi_data { - struct completion read_complete; // Synchronization primitive for signaling message read completion - struct ipmi_addr address; // Structure to store the IPMI system interface address - struct ipmi_user *user; // Pointer to IPMI user created by the kernel - int interface; // Interface identifier for the IPMI system - - struct kernel_ipmi_msg tx_message; // Message structure for sending IPMI commands - long tx_msgid; // Message ID for tracking IPMI message transactions - - void *rx_msg_data; // Pointer to buffer for storing received IPMI message data - unsigned short rx_msg_len; // Length of the received IPMI message - unsigned char rx_result; // Result code from the received IPMI message - int rx_recv_type; // Type of the received message (e.g., system interface, LAN, etc.) - - struct ipmi_user_hndl ipmi_hndlrs; // IPMI handler structure for handling incoming IPMI messages - struct device *dev; // Device structure for logging errors -}; - -/* Function declarations */ - -/* - * Initialize IPMI data structure and create a user interface for communication. - * - * @param ipmi: Pointer to ipmi_data structure to be initialized. - * @param iface: IPMI interface identifier. - * @param dev: Device structure for logging errors. - * @return 0 on success, or an error code on failure. - */ -extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev); - -/* - * Send an IPMI command to the IPMI device and receive the response. - * - * @param ipmi: Pointer to ipmi_data structure containing IPMI communication information. - * @param cmd: IPMI command byte. - * @param tx_data: Pointer to data buffer for the command payload. - * @param tx_len: Length of the command payload data. - * @param rx_data: Pointer to buffer for storing the response data. - * @param rx_len: Length of the response data buffer. - * @return 0 on success, or an error code on failure. - */ -extern int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len); - -#endif /* ACCTON_IPMI_INTF_H */ diff --git a/packages/platforms/accton/x86-64/as9737-32db/modules/builds/Makefile b/packages/platforms/accton/x86-64/as9737-32db/modules/builds/Makefile index eb85ba871..d113b4bcc 100644 --- a/packages/platforms/accton/x86-64/as9737-32db/modules/builds/Makefile +++ b/packages/platforms/accton/x86-64/as9737-32db/modules/builds/Makefile @@ -1,5 +1,6 @@ KERNELS := onl-kernel-6.1-lts-x86-64-all:amd64 -KMODULES := src +KINCLUDES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h +KMODULES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c $(wildcard src/*.c) VENDOR := accton BASENAME := x86-64-accton-as9737-32db ARCH := x86_64 diff --git a/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/Makefile b/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/Makefile deleted file mode 100644 index 1ce36b1eb..000000000 --- a/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -obj-m += accton_ipmi_intf.o -obj-m += x86-64-accton-as9737-32db-cpld.o -obj-m += x86-64-accton-as9737-32db-fan.o -obj-m += x86-64-accton-as9737-32db-fpga.o -obj-m += x86-64-accton-as9737-32db-i2c-ocores.o -obj-m += x86-64-accton-as9737-32db-leds.o -obj-m += x86-64-accton-as9737-32db-mux.o -obj-m += x86-64-accton-as9737-32db-psu.o -obj-m += x86-64-accton-as9737-32db-sys.o -obj-m += x86-64-accton-as9737-32db-thermal.o diff --git a/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/accton_ipmi_intf.c b/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/accton_ipmi_intf.c deleted file mode 100644 index d66fbc2b3..000000000 --- a/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/accton_ipmi_intf.c +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface implementation - */ -#include -#include -#include -#include "accton_ipmi_intf.h" - -#define ACCTON_IPMI_NETFN 0x34 -#define IPMI_TIMEOUT (5 * HZ) -#define IPMI_ERR_RETRY_TIMES 0 -#define RAW_CMD_BUF_SIZE 40 - -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); - -/* Functions to talk to the IPMI layer */ - -/* Initialize IPMI data structure and create a user interface for communication */ -int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev) -{ - int err; - - if (!ipmi || !dev) - return -EINVAL; - - init_completion(&ipmi->read_complete); - - // Initialize IPMI address - ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - ipmi->address.channel = IPMI_BMC_CHANNEL; - ipmi->address.data[0] = 0; - ipmi->interface = iface; - ipmi->dev = dev; // Storing the device for future reference - - // Initialize message buffers - ipmi->tx_msgid = 0; - ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; - - // Assign the message handler - ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; - - // Create IPMI messaging interface user - err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, - ipmi, &ipmi->user); - if (err < 0) { - dev_err(dev, - "Unable to register user with IPMI interface %d, err: %d\n", - ipmi->interface, err); - return err; - } - - return 0; -} -EXPORT_SYMBOL(init_ipmi_data); - -/* Handler function for receiving IPMI messages */ -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) -{ - unsigned short rx_len; - struct ipmi_data *ipmi = user_msg_data; - - // Check for message ID mismatch - if (msg->msgid != ipmi->tx_msgid) { - dev_err(ipmi->dev, "Mismatch between received msgid " - "(%02x) and transmitted msgid (%02x)!\n", - (int)msg->msgid, (int)ipmi->tx_msgid); - ipmi_free_recv_msg(msg); - return; - } - - // Handle received message type - ipmi->rx_recv_type = msg->recv_type; - - // Parse message data - if (msg->msg.data_len > 0) - ipmi->rx_result = msg->msg.data[0]; - else - ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; - - // Copy remaining message data if available - if (msg->msg.data_len > 1) { - rx_len = msg->msg.data_len - 1; - if (ipmi->rx_msg_len < rx_len) - rx_len = ipmi->rx_msg_len; - - ipmi->rx_msg_len = rx_len; - memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); - } else { - ipmi->rx_msg_len = 0; - } - - // Free the received message and signal completion - ipmi_free_recv_msg(msg); - complete(&ipmi->read_complete); -} - -static void _ipmi_log_error(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - int status, int retry) -{ - int i, pos; - char *cmdline = NULL; - char raw_cmd[RAW_CMD_BUF_SIZE] = { 0 }; - - // Format the command and data into a raw command string - pos = snprintf(raw_cmd, sizeof(raw_cmd), "0x%02x", cmd); - for (i = 0; i < tx_len && pos < sizeof(raw_cmd); i++) { - pos += snprintf(raw_cmd + pos, sizeof(raw_cmd) - pos, - " 0x%02x", tx_data[i]); - } - - // Log the error message - cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); - dev_err(ipmi->dev, - "ipmi_send_message: retry(%d), error(%d), cmd(%s) raw_cmd=[%s]\r\n", - retry, status, cmdline ? cmdline : "", raw_cmd); - - if (cmdline) { - kfree(cmdline); - } -} - -/* Send an IPMI command */ -static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int err; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - // Initialize IPMI message - ipmi->tx_message.cmd = cmd; - ipmi->tx_message.data = tx_len ? tx_data : NULL; - ipmi->tx_message.data_len = tx_len; - ipmi->rx_msg_data = rx_len ? rx_data : NULL; - ipmi->rx_msg_len = rx_len; - - // Validate the IPMI address - err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); - if (err) { - dev_err(ipmi->dev, "Invalid IPMI address: %x\n", err); - return err; - } - - // Increment message ID and send the request - ipmi->tx_msgid++; - err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, - &ipmi->tx_message, ipmi, 0, 0, 0); - if (err) { - dev_err(ipmi->dev, "IPMI request_settime failed: %x\n", err); - return err; - } - - // Wait for the message to complete - err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!err) { - dev_err(ipmi->dev, "IPMI command timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - -/* Send an IPMI command to the IPMI device and receive the response */ -int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int status = 0, retry = 0; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { - status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len); - if (unlikely(status != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - if (unlikely(ipmi->rx_result != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - // Success, exit the retry loop - break; - } - - return status; -} - -EXPORT_SYMBOL(ipmi_send_message); - -static int __init ipmi_module_init(void) -{ - printk(KERN_INFO "Accton IPMI Module loaded\n"); - return 0; -} - -static void __exit ipmi_module_exit(void) -{ - printk(KERN_INFO "Accton IPMI Module unloaded\n"); -} - -module_init(ipmi_module_init); -module_exit(ipmi_module_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("Accton IPMI messaging module"); -MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/accton_ipmi_intf.h b/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/accton_ipmi_intf.h deleted file mode 100644 index 4b2fe59f9..000000000 --- a/packages/platforms/accton/x86-64/as9737-32db/modules/builds/src/accton_ipmi_intf.h +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface declarations - */ - -#ifndef ACCTON_IPMI_INTF_H -#define ACCTON_IPMI_INTF_H - -#include -#include - -/* Structure to hold IPMI (Intelligent Platform Management Interface) data */ -struct ipmi_data { - struct completion read_complete; // Synchronization primitive for signaling message read completion - struct ipmi_addr address; // Structure to store the IPMI system interface address - struct ipmi_user *user; // Pointer to IPMI user created by the kernel - int interface; // Interface identifier for the IPMI system - - struct kernel_ipmi_msg tx_message; // Message structure for sending IPMI commands - long tx_msgid; // Message ID for tracking IPMI message transactions - - void *rx_msg_data; // Pointer to buffer for storing received IPMI message data - unsigned short rx_msg_len; // Length of the received IPMI message - unsigned char rx_result; // Result code from the received IPMI message - int rx_recv_type; // Type of the received message (e.g., system interface, LAN, etc.) - - struct ipmi_user_hndl ipmi_hndlrs; // IPMI handler structure for handling incoming IPMI messages - struct device *dev; // Device structure for logging errors -}; - -/* Function declarations */ - -/* - * Initialize IPMI data structure and create a user interface for communication. - * - * @param ipmi: Pointer to ipmi_data structure to be initialized. - * @param iface: IPMI interface identifier. - * @param dev: Device structure for logging errors. - * @return 0 on success, or an error code on failure. - */ -extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev); - -/* - * Send an IPMI command to the IPMI device and receive the response. - * - * @param ipmi: Pointer to ipmi_data structure containing IPMI communication information. - * @param cmd: IPMI command byte. - * @param tx_data: Pointer to data buffer for the command payload. - * @param tx_len: Length of the command payload data. - * @param rx_data: Pointer to buffer for storing the response data. - * @param rx_len: Length of the response data buffer. - * @return 0 on success, or an error code on failure. - */ -extern int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len); - -#endif /* ACCTON_IPMI_INTF_H */ diff --git a/packages/platforms/accton/x86-64/as9817-64/as9817-64d/modules/builds/Makefile b/packages/platforms/accton/x86-64/as9817-64/as9817-64d/modules/builds/Makefile index b182e0aec..ec17b53fa 100644 --- a/packages/platforms/accton/x86-64/as9817-64/as9817-64d/modules/builds/Makefile +++ b/packages/platforms/accton/x86-64/as9817-64/as9817-64d/modules/builds/Makefile @@ -1,5 +1,6 @@ KERNELS := onl-kernel-6.12-lts-x86-64-all:amd64 -KMODULES := $(ONL)/packages/platforms/accton/x86-64/as9817-64/src/modules/ +KINCLUDES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h +KMODULES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c $(wildcard $(ONL)/packages/platforms/accton/x86-64/as9817-64/src/modules/*.c) VENDOR := accton BASENAME := x86-64-accton-as9817-64d ARCH := x86_64 diff --git a/packages/platforms/accton/x86-64/as9817-64/as9817-64o/modules/builds/Makefile b/packages/platforms/accton/x86-64/as9817-64/as9817-64o/modules/builds/Makefile index 079c62eeb..77df57a07 100644 --- a/packages/platforms/accton/x86-64/as9817-64/as9817-64o/modules/builds/Makefile +++ b/packages/platforms/accton/x86-64/as9817-64/as9817-64o/modules/builds/Makefile @@ -1,5 +1,6 @@ KERNELS := onl-kernel-6.12-lts-x86-64-all:amd64 -KMODULES := $(ONL)/packages/platforms/accton/x86-64/as9817-64/src/modules/ +KINCLUDES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h +KMODULES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c $(wildcard $(ONL)/packages/platforms/accton/x86-64/as9817-64/src/modules/*.c) VENDOR := accton BASENAME := x86-64-accton-as9817-64o ARCH := x86_64 diff --git a/packages/platforms/accton/x86-64/as9817-64/src/modules/Makefile b/packages/platforms/accton/x86-64/as9817-64/src/modules/Makefile deleted file mode 100644 index 7ccd2ca3f..000000000 --- a/packages/platforms/accton/x86-64/as9817-64/src/modules/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -obj-m += accton_ipmi_intf.o -obj-m += x86-64-accton-as9817-64-fan.o -obj-m += x86-64-accton-as9817-64-fpga.o -obj-m += x86-64-accton-as9817-64-i2c-ocores.o -obj-m += x86-64-accton-as9817-64-leds.o -obj-m += x86-64-accton-as9817-64-psu.o -obj-m += x86-64-accton-as9817-64-sys.o -obj-m += x86-64-accton-as9817-64-thermal.o -obj-m += x86-64-accton-as9817-64-mux.o diff --git a/packages/platforms/accton/x86-64/as9817-64/src/modules/accton_ipmi_intf.c b/packages/platforms/accton/x86-64/as9817-64/src/modules/accton_ipmi_intf.c deleted file mode 100644 index 48a0c9acf..000000000 --- a/packages/platforms/accton/x86-64/as9817-64/src/modules/accton_ipmi_intf.c +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface implementation - */ -#include -#include -#include -#include "accton_ipmi_intf.h" - -#define ACCTON_IPMI_NETFN 0x34 -#define IPMI_TIMEOUT (5 * HZ) -#define IPMI_ERR_RETRY_TIMES 1 -#define RAW_CMD_BUF_SIZE 40 - -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); - -/* Functions to talk to the IPMI layer */ - -/* Initialize IPMI data structure and create a user interface for communication */ -int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev) -{ - int err; - - if (!ipmi || !dev) - return -EINVAL; - - init_completion(&ipmi->read_complete); - - // Initialize IPMI address - ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - ipmi->address.channel = IPMI_BMC_CHANNEL; - ipmi->address.data[0] = 0; - ipmi->interface = iface; - ipmi->dev = dev; // Storing the device for future reference - - // Initialize message buffers - ipmi->tx_msgid = 0; - ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; - - // Assign the message handler - ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; - - // Create IPMI messaging interface user - err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, - ipmi, &ipmi->user); - if (err < 0) { - dev_err(dev, - "Unable to register user with IPMI interface %d, err: %d\n", - ipmi->interface, err); - return err; - } - - return 0; -} -EXPORT_SYMBOL(init_ipmi_data); - -/* Handler function for receiving IPMI messages */ -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) -{ - unsigned short rx_len; - struct ipmi_data *ipmi = user_msg_data; - - // Check for message ID mismatch - if (msg->msgid != ipmi->tx_msgid) { - dev_err(ipmi->dev, "Mismatch between received msgid " - "(%02x) and transmitted msgid (%02x)!\n", - (int)msg->msgid, (int)ipmi->tx_msgid); - ipmi_free_recv_msg(msg); - return; - } - - // Handle received message type - ipmi->rx_recv_type = msg->recv_type; - - // Parse message data - if (msg->msg.data_len > 0) - ipmi->rx_result = msg->msg.data[0]; - else - ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; - - // Copy remaining message data if available - if (msg->msg.data_len > 1) { - rx_len = msg->msg.data_len - 1; - if (ipmi->rx_msg_len < rx_len) - rx_len = ipmi->rx_msg_len; - - ipmi->rx_msg_len = rx_len; - memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); - } else { - ipmi->rx_msg_len = 0; - } - - // Free the received message and signal completion - ipmi_free_recv_msg(msg); - complete(&ipmi->read_complete); -} - -static void _ipmi_log_error(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - int status, int retry) -{ - int i, pos; - char *cmdline = NULL; - char raw_cmd[RAW_CMD_BUF_SIZE] = { 0 }; - - // Format the command and data into a raw command string - pos = snprintf(raw_cmd, sizeof(raw_cmd), "0x%02x", cmd); - for (i = 0; i < tx_len && pos < sizeof(raw_cmd); i++) { - pos += snprintf(raw_cmd + pos, sizeof(raw_cmd) - pos, - " 0x%02x", tx_data[i]); - } - - // Log the error message - cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); - dev_err(ipmi->dev, - "ipmi_send_message: retry(%d), error(%d), cmd(%s) raw_cmd=[%s]\r\n", - retry, status, cmdline ? cmdline : "", raw_cmd); - - if (cmdline) { - kfree(cmdline); - } -} - -/* Send an IPMI command */ -static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int err; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - // Initialize IPMI message - ipmi->tx_message.cmd = cmd; - ipmi->tx_message.data = tx_len ? tx_data : NULL; - ipmi->tx_message.data_len = tx_len; - ipmi->rx_msg_data = rx_len ? rx_data : NULL; - ipmi->rx_msg_len = rx_len; - - // Validate the IPMI address - err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); - if (err) { - dev_err(ipmi->dev, "Invalid IPMI address: %x\n", err); - return err; - } - - // Increment message ID and send the request - ipmi->tx_msgid++; - err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, - &ipmi->tx_message, ipmi, 0, 0, 0); - if (err) { - dev_err(ipmi->dev, "IPMI request_settime failed: %x\n", err); - return err; - } - - // Wait for the message to complete - err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!err) { - dev_err(ipmi->dev, "IPMI command timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - -/* Send an IPMI command to the IPMI device and receive the response */ -int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int status = 0, retry = 0; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { - status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len); - if (unlikely(status != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - if (unlikely(ipmi->rx_result != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - // Success, exit the retry loop - break; - } - - return status; -} - -EXPORT_SYMBOL(ipmi_send_message); - -static int __init ipmi_module_init(void) -{ - printk(KERN_INFO "Accton IPMI Module loaded\n"); - return 0; -} - -static void __exit ipmi_module_exit(void) -{ - printk(KERN_INFO "Accton IPMI Module unloaded\n"); -} - -module_init(ipmi_module_init); -module_exit(ipmi_module_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("Accton IPMI messaging module"); -MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/x86-64/as9817-64/src/modules/accton_ipmi_intf.h b/packages/platforms/accton/x86-64/as9817-64/src/modules/accton_ipmi_intf.h deleted file mode 100644 index 4b2fe59f9..000000000 --- a/packages/platforms/accton/x86-64/as9817-64/src/modules/accton_ipmi_intf.h +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface declarations - */ - -#ifndef ACCTON_IPMI_INTF_H -#define ACCTON_IPMI_INTF_H - -#include -#include - -/* Structure to hold IPMI (Intelligent Platform Management Interface) data */ -struct ipmi_data { - struct completion read_complete; // Synchronization primitive for signaling message read completion - struct ipmi_addr address; // Structure to store the IPMI system interface address - struct ipmi_user *user; // Pointer to IPMI user created by the kernel - int interface; // Interface identifier for the IPMI system - - struct kernel_ipmi_msg tx_message; // Message structure for sending IPMI commands - long tx_msgid; // Message ID for tracking IPMI message transactions - - void *rx_msg_data; // Pointer to buffer for storing received IPMI message data - unsigned short rx_msg_len; // Length of the received IPMI message - unsigned char rx_result; // Result code from the received IPMI message - int rx_recv_type; // Type of the received message (e.g., system interface, LAN, etc.) - - struct ipmi_user_hndl ipmi_hndlrs; // IPMI handler structure for handling incoming IPMI messages - struct device *dev; // Device structure for logging errors -}; - -/* Function declarations */ - -/* - * Initialize IPMI data structure and create a user interface for communication. - * - * @param ipmi: Pointer to ipmi_data structure to be initialized. - * @param iface: IPMI interface identifier. - * @param dev: Device structure for logging errors. - * @return 0 on success, or an error code on failure. - */ -extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev); - -/* - * Send an IPMI command to the IPMI device and receive the response. - * - * @param ipmi: Pointer to ipmi_data structure containing IPMI communication information. - * @param cmd: IPMI command byte. - * @param tx_data: Pointer to data buffer for the command payload. - * @param tx_len: Length of the command payload data. - * @param rx_data: Pointer to buffer for storing the response data. - * @param rx_len: Length of the response data buffer. - * @return 0 on success, or an error code on failure. - */ -extern int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len); - -#endif /* ACCTON_IPMI_INTF_H */ diff --git a/packages/platforms/accton/x86-64/as9817-64/src/modules/x86-64-accton-as9817-64-fpga.c b/packages/platforms/accton/x86-64/as9817-64/src/modules/x86-64-accton-as9817-64-fpga.c index 7a0648bb3..b1bacdd04 100644 --- a/packages/platforms/accton/x86-64/as9817-64/src/modules/x86-64-accton-as9817-64-fpga.c +++ b/packages/platforms/accton/x86-64/as9817-64/src/modules/x86-64-accton-as9817-64-fpga.c @@ -157,9 +157,16 @@ struct as9817_64_fpga_data { }; static struct platform_device *pdev = NULL; -extern spinlock_t cpld_access_lock; -extern int wait_spi(u32 mask, unsigned long timeout); -extern void __iomem *spi_busy_reg; + +/* + * These symbols are exported by x86-64-accton-as9817-64-i2c-ocores.ko and + * resolved at insmod time. Marked weak so modpost does not report them as + * undefined during the fpga.ko build pass (each .c is built in an isolated + * modpost pass, so cross-.ko symbols are not visible at build time). + */ +extern spinlock_t cpld_access_lock __attribute__((weak)); +extern int wait_spi(u32 mask, unsigned long timeout_us) __attribute__((weak)); +extern void __iomem *spi_busy_reg __attribute__((weak)); /*********************************************** * enum define diff --git a/packages/platforms/accton/x86-64/as9926-24db/modules/builds/Makefile b/packages/platforms/accton/x86-64/as9926-24db/modules/builds/Makefile index bd931f94d..a157cf35c 100644 --- a/packages/platforms/accton/x86-64/as9926-24db/modules/builds/Makefile +++ b/packages/platforms/accton/x86-64/as9926-24db/modules/builds/Makefile @@ -1,5 +1,6 @@ KERNELS := onl-kernel-6.1-lts-x86-64-all:amd64 -KMODULES := src +KINCLUDES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h +KMODULES := $(ONL)/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c $(wildcard src/*.c) VENDOR := accton BASENAME := x86-64-accton-as9926-24db ARCH := x86_64 diff --git a/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/Makefile b/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/Makefile deleted file mode 100644 index 5b0579026..000000000 --- a/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/Makefile +++ /dev/null @@ -1,7 +0,0 @@ -obj-m += accton_ipmi_intf.o -obj-m += x86-64-accton-as9926-24db-fan.o -obj-m += x86-64-accton-as9926-24db-leds.o -obj-m += x86-64-accton-as9926-24db-psu.o -obj-m += x86-64-accton-as9926-24db-sfp.o -obj-m += x86-64-accton-as9926-24db-sys.o -obj-m += x86-64-accton-as9926-24db-thermal.o \ No newline at end of file diff --git a/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/accton_ipmi_intf.c b/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/accton_ipmi_intf.c deleted file mode 100644 index 48a0c9acf..000000000 --- a/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/accton_ipmi_intf.c +++ /dev/null @@ -1,232 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface implementation - */ -#include -#include -#include -#include "accton_ipmi_intf.h" - -#define ACCTON_IPMI_NETFN 0x34 -#define IPMI_TIMEOUT (5 * HZ) -#define IPMI_ERR_RETRY_TIMES 1 -#define RAW_CMD_BUF_SIZE 40 - -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); - -/* Functions to talk to the IPMI layer */ - -/* Initialize IPMI data structure and create a user interface for communication */ -int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev) -{ - int err; - - if (!ipmi || !dev) - return -EINVAL; - - init_completion(&ipmi->read_complete); - - // Initialize IPMI address - ipmi->address.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; - ipmi->address.channel = IPMI_BMC_CHANNEL; - ipmi->address.data[0] = 0; - ipmi->interface = iface; - ipmi->dev = dev; // Storing the device for future reference - - // Initialize message buffers - ipmi->tx_msgid = 0; - ipmi->tx_message.netfn = ACCTON_IPMI_NETFN; - - // Assign the message handler - ipmi->ipmi_hndlrs.ipmi_recv_hndl = ipmi_msg_handler; - - // Create IPMI messaging interface user - err = ipmi_create_user(ipmi->interface, &ipmi->ipmi_hndlrs, - ipmi, &ipmi->user); - if (err < 0) { - dev_err(dev, - "Unable to register user with IPMI interface %d, err: %d\n", - ipmi->interface, err); - return err; - } - - return 0; -} -EXPORT_SYMBOL(init_ipmi_data); - -/* Handler function for receiving IPMI messages */ -static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) -{ - unsigned short rx_len; - struct ipmi_data *ipmi = user_msg_data; - - // Check for message ID mismatch - if (msg->msgid != ipmi->tx_msgid) { - dev_err(ipmi->dev, "Mismatch between received msgid " - "(%02x) and transmitted msgid (%02x)!\n", - (int)msg->msgid, (int)ipmi->tx_msgid); - ipmi_free_recv_msg(msg); - return; - } - - // Handle received message type - ipmi->rx_recv_type = msg->recv_type; - - // Parse message data - if (msg->msg.data_len > 0) - ipmi->rx_result = msg->msg.data[0]; - else - ipmi->rx_result = IPMI_UNKNOWN_ERR_COMPLETION_CODE; - - // Copy remaining message data if available - if (msg->msg.data_len > 1) { - rx_len = msg->msg.data_len - 1; - if (ipmi->rx_msg_len < rx_len) - rx_len = ipmi->rx_msg_len; - - ipmi->rx_msg_len = rx_len; - memcpy(ipmi->rx_msg_data, msg->msg.data + 1, ipmi->rx_msg_len); - } else { - ipmi->rx_msg_len = 0; - } - - // Free the received message and signal completion - ipmi_free_recv_msg(msg); - complete(&ipmi->read_complete); -} - -static void _ipmi_log_error(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - int status, int retry) -{ - int i, pos; - char *cmdline = NULL; - char raw_cmd[RAW_CMD_BUF_SIZE] = { 0 }; - - // Format the command and data into a raw command string - pos = snprintf(raw_cmd, sizeof(raw_cmd), "0x%02x", cmd); - for (i = 0; i < tx_len && pos < sizeof(raw_cmd); i++) { - pos += snprintf(raw_cmd + pos, sizeof(raw_cmd) - pos, - " 0x%02x", tx_data[i]); - } - - // Log the error message - cmdline = kstrdup_quotable_cmdline(current, GFP_KERNEL); - dev_err(ipmi->dev, - "ipmi_send_message: retry(%d), error(%d), cmd(%s) raw_cmd=[%s]\r\n", - retry, status, cmdline ? cmdline : "", raw_cmd); - - if (cmdline) { - kfree(cmdline); - } -} - -/* Send an IPMI command */ -static int _ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int err; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - // Initialize IPMI message - ipmi->tx_message.cmd = cmd; - ipmi->tx_message.data = tx_len ? tx_data : NULL; - ipmi->tx_message.data_len = tx_len; - ipmi->rx_msg_data = rx_len ? rx_data : NULL; - ipmi->rx_msg_len = rx_len; - - // Validate the IPMI address - err = ipmi_validate_addr(&ipmi->address, sizeof(ipmi->address)); - if (err) { - dev_err(ipmi->dev, "Invalid IPMI address: %x\n", err); - return err; - } - - // Increment message ID and send the request - ipmi->tx_msgid++; - err = ipmi_request_settime(ipmi->user, &ipmi->address, ipmi->tx_msgid, - &ipmi->tx_message, ipmi, 0, 0, 0); - if (err) { - dev_err(ipmi->dev, "IPMI request_settime failed: %x\n", err); - return err; - } - - // Wait for the message to complete - err = wait_for_completion_timeout(&ipmi->read_complete, IPMI_TIMEOUT); - if (!err) { - dev_err(ipmi->dev, "IPMI command timeout\n"); - return -ETIMEDOUT; - } - - return 0; -} - -/* Send an IPMI command to the IPMI device and receive the response */ -int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len) -{ - int status = 0, retry = 0; - - // Validate the input parameters - if ((tx_len && !tx_data) || (rx_len && !rx_data)) { - return -EINVAL; - } - - for (retry = 0; retry <= IPMI_ERR_RETRY_TIMES; retry++) { - status = _ipmi_send_message(ipmi, cmd, tx_data, tx_len, rx_data, rx_len); - if (unlikely(status != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - if (unlikely(ipmi->rx_result != 0)) { - _ipmi_log_error(ipmi, cmd, tx_data, tx_len, status, retry); - continue; - } - - // Success, exit the retry loop - break; - } - - return status; -} - -EXPORT_SYMBOL(ipmi_send_message); - -static int __init ipmi_module_init(void) -{ - printk(KERN_INFO "Accton IPMI Module loaded\n"); - return 0; -} - -static void __exit ipmi_module_exit(void) -{ - printk(KERN_INFO "Accton IPMI Module unloaded\n"); -} - -module_init(ipmi_module_init); -module_exit(ipmi_module_exit); - -MODULE_AUTHOR("Brandon Chuang "); -MODULE_DESCRIPTION("Accton IPMI messaging module"); -MODULE_LICENSE("GPL"); diff --git a/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/accton_ipmi_intf.h b/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/accton_ipmi_intf.h deleted file mode 100644 index 4b2fe59f9..000000000 --- a/packages/platforms/accton/x86-64/as9926-24db/modules/builds/src/accton_ipmi_intf.h +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0 -/* - * Copyright 2024 Accton Technology Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * - * Description: - * IPMI driver related interface declarations - */ - -#ifndef ACCTON_IPMI_INTF_H -#define ACCTON_IPMI_INTF_H - -#include -#include - -/* Structure to hold IPMI (Intelligent Platform Management Interface) data */ -struct ipmi_data { - struct completion read_complete; // Synchronization primitive for signaling message read completion - struct ipmi_addr address; // Structure to store the IPMI system interface address - struct ipmi_user *user; // Pointer to IPMI user created by the kernel - int interface; // Interface identifier for the IPMI system - - struct kernel_ipmi_msg tx_message; // Message structure for sending IPMI commands - long tx_msgid; // Message ID for tracking IPMI message transactions - - void *rx_msg_data; // Pointer to buffer for storing received IPMI message data - unsigned short rx_msg_len; // Length of the received IPMI message - unsigned char rx_result; // Result code from the received IPMI message - int rx_recv_type; // Type of the received message (e.g., system interface, LAN, etc.) - - struct ipmi_user_hndl ipmi_hndlrs; // IPMI handler structure for handling incoming IPMI messages - struct device *dev; // Device structure for logging errors -}; - -/* Function declarations */ - -/* - * Initialize IPMI data structure and create a user interface for communication. - * - * @param ipmi: Pointer to ipmi_data structure to be initialized. - * @param iface: IPMI interface identifier. - * @param dev: Device structure for logging errors. - * @return 0 on success, or an error code on failure. - */ -extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev); - -/* - * Send an IPMI command to the IPMI device and receive the response. - * - * @param ipmi: Pointer to ipmi_data structure containing IPMI communication information. - * @param cmd: IPMI command byte. - * @param tx_data: Pointer to data buffer for the command payload. - * @param tx_len: Length of the command payload data. - * @param rx_data: Pointer to buffer for storing the response data. - * @param rx_len: Length of the response data buffer. - * @return 0 on success, or an error code on failure. - */ -extern int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, - unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len); - -#endif /* ACCTON_IPMI_INTF_H */ diff --git a/packages/platforms/accton/x86-64/as7535-28xb/modules/builds/src/accton_ipmi_intf.c b/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c similarity index 100% rename from packages/platforms/accton/x86-64/as7535-28xb/modules/builds/src/accton_ipmi_intf.c rename to packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.c diff --git a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/accton_ipmi_intf.h b/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h similarity index 97% rename from packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/accton_ipmi_intf.h rename to packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h index 4b2fe59f9..5c88043a0 100644 --- a/packages/platforms/accton/x86-64/as7926-40xfb/modules/builds/src/accton_ipmi_intf.h +++ b/packages/platforms/accton/x86-64/common/modules/builds/ipmi/accton_ipmi_intf.h @@ -52,7 +52,7 @@ struct ipmi_data { * @param dev: Device structure for logging errors. * @return 0 on success, or an error code on failure. */ -extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev); +extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev) __attribute__((weak)); /* * Send an IPMI command to the IPMI device and receive the response. @@ -67,6 +67,6 @@ extern int init_ipmi_data(struct ipmi_data *ipmi, int iface, struct device *dev) */ extern int ipmi_send_message(struct ipmi_data *ipmi, unsigned char cmd, unsigned char *tx_data, unsigned short tx_len, - unsigned char *rx_data, unsigned short rx_len); + unsigned char *rx_data, unsigned short rx_len) __attribute__((weak)); #endif /* ACCTON_IPMI_INTF_H */