From bc55e0545a826a81eeb5139a4d87a63a46d979c9 Mon Sep 17 00:00:00 2001 From: Shijith Thotton Date: Sat, 25 Mar 2017 11:54:43 +0530 Subject: [PATCH] net/liquidio: add APIs to alloc and send control command Signed-off-by: Shijith Thotton Signed-off-by: Jerin Jacob Signed-off-by: Derek Chickles Signed-off-by: Venkat Koppula Signed-off-by: Srisivasubramanian S Signed-off-by: Mallesham Jatharakonda --- drivers/net/liquidio/base/lio_hw_defs.h | 1 + drivers/net/liquidio/lio_ethdev.h | 6 ++ drivers/net/liquidio/lio_rxtx.c | 82 +++++++++++++++++++++++++ drivers/net/liquidio/lio_rxtx.h | 44 +++++++++++++ 4 files changed, 133 insertions(+) diff --git a/drivers/net/liquidio/base/lio_hw_defs.h b/drivers/net/liquidio/base/lio_hw_defs.h index e3f18e36d4..d38c835208 100644 --- a/drivers/net/liquidio/base/lio_hw_defs.h +++ b/drivers/net/liquidio/base/lio_hw_defs.h @@ -122,6 +122,7 @@ enum octeon_tag_type { /** LIO_OPCODE subcodes */ /* This subcode is sent by core PCI driver to indicate cores are ready. */ #define LIO_OPCODE_NW_DATA 0x02 /* network packet data */ +#define LIO_OPCODE_CMD 0x03 #define LIO_OPCODE_INFO 0x04 #define LIO_OPCODE_IF_CFG 0x09 diff --git a/drivers/net/liquidio/lio_ethdev.h b/drivers/net/liquidio/lio_ethdev.h index 98ff493aec..7b5343a717 100644 --- a/drivers/net/liquidio/lio_ethdev.h +++ b/drivers/net/liquidio/lio_ethdev.h @@ -44,6 +44,12 @@ #define LIO_DEV(_eth_dev) ((_eth_dev)->data->dev_private) +/* LIO Response condition variable */ +struct lio_dev_ctrl_cmd { + struct rte_eth_dev *eth_dev; + uint64_t cond; +}; + enum lio_bus_speed { LIO_LINK_SPEED_UNKNOWN = 0, LIO_LINK_SPEED_10000 = 10000 diff --git a/drivers/net/liquidio/lio_rxtx.c b/drivers/net/liquidio/lio_rxtx.c index d7e17bf76d..c12960c822 100644 --- a/drivers/net/liquidio/lio_rxtx.c +++ b/drivers/net/liquidio/lio_rxtx.c @@ -1557,6 +1557,88 @@ lio_dev_cleanup_iq(struct lio_device *lio_dev, int iq_no) return count ? 0 : 1; } +static void +lio_ctrl_cmd_callback(uint32_t status __rte_unused, void *sc_ptr) +{ + struct lio_soft_command *sc = sc_ptr; + struct lio_dev_ctrl_cmd *ctrl_cmd; + struct lio_ctrl_pkt *ctrl_pkt; + + ctrl_pkt = (struct lio_ctrl_pkt *)sc->ctxptr; + ctrl_cmd = ctrl_pkt->ctrl_cmd; + ctrl_cmd->cond = 1; + + lio_free_soft_command(sc); +} + +static inline struct lio_soft_command * +lio_alloc_ctrl_pkt_sc(struct lio_device *lio_dev, + struct lio_ctrl_pkt *ctrl_pkt) +{ + struct lio_soft_command *sc = NULL; + uint32_t uddsize, datasize; + uint32_t rdatasize; + uint8_t *data; + + uddsize = (uint32_t)(ctrl_pkt->ncmd.s.more * 8); + + datasize = OCTEON_CMD_SIZE + uddsize; + rdatasize = (ctrl_pkt->wait_time) ? 16 : 0; + + sc = lio_alloc_soft_command(lio_dev, datasize, + rdatasize, sizeof(struct lio_ctrl_pkt)); + if (sc == NULL) + return NULL; + + rte_memcpy(sc->ctxptr, ctrl_pkt, sizeof(struct lio_ctrl_pkt)); + + data = (uint8_t *)sc->virtdptr; + + rte_memcpy(data, &ctrl_pkt->ncmd, OCTEON_CMD_SIZE); + + lio_swap_8B_data((uint64_t *)data, OCTEON_CMD_SIZE >> 3); + + if (uddsize) { + /* Endian-Swap for UDD should have been done by caller. */ + rte_memcpy(data + OCTEON_CMD_SIZE, ctrl_pkt->udd, uddsize); + } + + sc->iq_no = (uint32_t)ctrl_pkt->iq_no; + + lio_prepare_soft_command(lio_dev, sc, + LIO_OPCODE, LIO_OPCODE_CMD, + 0, 0, 0); + + sc->callback = lio_ctrl_cmd_callback; + sc->callback_arg = sc; + sc->wait_time = ctrl_pkt->wait_time; + + return sc; +} + +int +lio_send_ctrl_pkt(struct lio_device *lio_dev, struct lio_ctrl_pkt *ctrl_pkt) +{ + struct lio_soft_command *sc = NULL; + int retval; + + sc = lio_alloc_ctrl_pkt_sc(lio_dev, ctrl_pkt); + if (sc == NULL) { + lio_dev_err(lio_dev, "soft command allocation failed\n"); + return -1; + } + + retval = lio_send_soft_command(lio_dev, sc); + if (retval == LIO_IQ_SEND_FAILED) { + lio_free_soft_command(sc); + lio_dev_err(lio_dev, "Port: %d soft command: %d send failed status: %x\n", + lio_dev->port_id, ctrl_pkt->ncmd.s.cmd, retval); + return -1; + } + + return retval; +} + /** Send data packet to the device * @param lio_dev - lio device pointer * @param ndata - control structure with queueing, and buffer information diff --git a/drivers/net/liquidio/lio_rxtx.h b/drivers/net/liquidio/lio_rxtx.h index 964a884ef5..95d000753b 100644 --- a/drivers/net/liquidio/lio_rxtx.h +++ b/drivers/net/liquidio/lio_rxtx.h @@ -249,6 +249,40 @@ union octeon_cmd { #define OCTEON_CMD_SIZE (sizeof(union octeon_cmd)) +/* Maximum number of 8-byte words can be + * sent in a NIC control message. + */ +#define LIO_MAX_NCTRL_UDD 32 + +/* Structure of control information passed by driver to the BASE + * layer when sending control commands to Octeon device software. + */ +struct lio_ctrl_pkt { + /** Command to be passed to the Octeon device software. */ + union octeon_cmd ncmd; + + /** Send buffer */ + void *data; + uint64_t dmadata; + + /** Response buffer */ + void *rdata; + uint64_t dmardata; + + /** Additional data that may be needed by some commands. */ + uint64_t udd[LIO_MAX_NCTRL_UDD]; + + /** Input queue to use to send this command. */ + uint64_t iq_no; + + /** Time to wait for Octeon software to respond to this control command. + * If wait_time is 0, BASE assumes no response is expected. + */ + size_t wait_time; + + struct lio_dev_ctrl_cmd *ctrl_cmd; +}; + /** Structure of data information passed by driver to the BASE * layer when forwarding data to Octeon device software. */ @@ -570,6 +604,16 @@ int lio_send_soft_command(struct lio_device *lio_dev, struct lio_soft_command *sc); void lio_free_soft_command(struct lio_soft_command *sc); +/** Send control packet to the device + * @param lio_dev - lio device pointer + * @param nctrl - control structure with command, timeout, and callback info + * + * @returns IQ_FAILED if it failed to add to the input queue. IQ_STOP if it the + * queue should be stopped, and LIO_IQ_SEND_OK if it sent okay. + */ +int lio_send_ctrl_pkt(struct lio_device *lio_dev, + struct lio_ctrl_pkt *ctrl_pkt); + /** Maximum ordered requests to process in every invocation of * lio_process_ordered_list(). The function will continue to process requests * as long as it can find one that has finished processing. If it keeps -- 2.20.1