Hi, Andrew > > diff --git a/lib/librte_ether/rte_ethdev.c > > b/lib/librte_ether/rte_ethdev.c index 917557a..89cffcf 100644 > > --- a/lib/librte_ether/rte_ethdev.c > > +++ b/lib/librte_ether/rte_ethdev.c > > @@ -1588,6 +1588,18 @@ > rte_eth_dev_set_rx_queue_stats_mapping(uint8_t port_id, uint16_t > rx_queue_id, > > STAT_QMAP_RX); > > } > > > > +int > > +rte_eth_dev_fw_version_get(uint8_t port_id, char *fw_version, size_t > > +fw_size) { > > + struct rte_eth_dev *dev; > > + > > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV); > > + dev = &rte_eth_devices[port_id]; > > + > > + RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->fw_version_get, - > ENOTSUP); > > + return (*dev->dev_ops->fw_version_get)(dev, fw_version, fw_size); > > I think it would be good to handle difference from snprintf() behaviour here > and specify that fw_version_get callback has exactly snprintf()-like return > value. > It would allow to avoid > duplicated code in all drivers (adding 1 for terminating null, conversion of > success value to 0).
But I think it would be better to just keep the way it is. If I handle snpritf() behavior here, may the function rte_eth_dev_fw_version_get and ops fw_version_get will have different definition of return value. > Also I think warning about insufficient space is not required. It could be > intentional to call the first time with 0 (or some small) space to get > required > space to be (re)allocated. > May be debug level message would be useful. Good advice, when call this function with 0, this function will become a API to get firmware version size. I think we can remove the warning message here. > > > +} > > + > > void > > rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info > *dev_info) > > { > > diff --git a/lib/librte_ether/rte_ethdev.h > > b/lib/librte_ether/rte_ethdev.h index ded43d7..37a55ef 100644 > > --- a/lib/librte_ether/rte_ethdev.h > > +++ b/lib/librte_ether/rte_ethdev.h > > @@ -1177,6 +1177,10 @@ typedef uint32_t > (*eth_rx_queue_count_t)(struct rte_eth_dev *dev, > > typedef int (*eth_rx_descriptor_done_t)(void *rxq, uint16_t offset); > > /**< @internal Check DD bit of specific RX descriptor */ > > > > +typedef int (*eth_fw_version_get_t)(struct rte_eth_dev *dev, > > + char *fw_version, size_t fw_size); /**< > @internal Get > > +firmware information of an Ethernet device. */ > > + > > If we finally have different return value for > rte_eth_dev_fw_version_get() and here, > it would be useful to highlight it here. If I keep the handle of snprintf() return value in drivers, they will not have different return here, so the highlight is not necessary. > > typedef void (*eth_rxq_info_get_t)(struct rte_eth_dev *dev, > > uint16_t rx_queue_id, struct rte_eth_rxq_info *qinfo); > > > > @@ -1459,6 +1463,7 @@ struct eth_dev_ops { > > eth_dev_infos_get_t dev_infos_get; /**< Get device info. */ > > eth_rxq_info_get_t rxq_info_get; /**< retrieve RX queue > information. */ > > eth_txq_info_get_t txq_info_get; /**< retrieve TX queue > information. */ > > + eth_fw_version_get_t fw_version_get; /**< Get firmware > version. */ > > eth_dev_supported_ptypes_get_t dev_supported_ptypes_get; > > /**< Get packet types supported and identified by device. */ > > > > @@ -2396,6 +2401,27 @@ void rte_eth_macaddr_get(uint8_t port_id, > struct ether_addr *mac_addr); > > void rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info > > *dev_info); > > > > /** > > + * Retrieve the firmware version of a device. > > + * > > + * @param port_id > > + * The port identifier of the device. > > + * @param fw_version > > + * A array pointer to store the firmware version of a device, > > + * allocated by caller. > > + * @param fw_size > > + * The size of the array pointed by fw_version, which should be > > + * large enough to store firmware version of the device. > > + * @return > > + * - (0) if successful. > > + * - (-ENOTSUP) if operation is not supported. > > + * - (-ENODEV) if *port_id* invalid. > > + * - (>0) if *fw_size* is not enough to store firmware version, return > > + * the size of the non truncated string. > > It is OK for me to keep 0 for success here and it is right in this case to > include > terminating null iin the return value if size is insufficient (to cover > corner case > with empty FW version). > Please, highlight that terminating null is included here. It is the difference > from snprintf() and it should be 100% clear. > You are right, I'll highlight that the firmware version stored here is include '\0'. > > + */ > > +int rte_eth_dev_fw_version_get(uint8_t port_id, > > + char *fw_version, size_t fw_size); > > + > > +/** > > * Retrieve the supported packet types of an Ethernet device. > > * > > * When a packet type is announced as supported, it *must* be > > recognized by diff --git a/lib/librte_ether/rte_ether_version.map > > b/lib/librte_ether/rte_ether_version.map > > index 0c2859e..c6c9d0d 100644 > > --- a/lib/librte_ether/rte_ether_version.map > > +++ b/lib/librte_ether/rte_ether_version.map > > @@ -146,6 +146,7 @@ DPDK_17.02 { > > global: > > > > _rte_eth_dev_reset; > > + rte_eth_dev_fw_version_get; > > rte_flow_create; > > rte_flow_destroy; > > rte_flow_flush; >