net/liquidio: add APIs to alloc and send control command
authorShijith Thotton <shijith.thotton@caviumnetworks.com>
Sat, 25 Mar 2017 06:24:43 +0000 (11:54 +0530)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 4 Apr 2017 16:59:49 +0000 (18:59 +0200)
Signed-off-by: Shijith Thotton <shijith.thotton@caviumnetworks.com>
Signed-off-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
Signed-off-by: Derek Chickles <derek.chickles@caviumnetworks.com>
Signed-off-by: Venkat Koppula <venkat.koppula@caviumnetworks.com>
Signed-off-by: Srisivasubramanian S <ssrinivasan@caviumnetworks.com>
Signed-off-by: Mallesham Jatharakonda <mjatharakonda@oneconvergence.com>
drivers/net/liquidio/base/lio_hw_defs.h
drivers/net/liquidio/lio_ethdev.h
drivers/net/liquidio/lio_rxtx.c
drivers/net/liquidio/lio_rxtx.h

index e3f18e3..d38c835 100644 (file)
@@ -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
 
index 98ff493..7b5343a 100644 (file)
 
 #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
index d7e17bf..c12960c 100644 (file)
@@ -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
index 964a884..95d0007 100644 (file)
@@ -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