liquidio: CN23XX queue manipulation
[cascardo/linux.git] / drivers / net / ethernet / cavium / liquidio / lio_main.c
index 20d6942..cb58381 100644 (file)
@@ -21,8 +21,6 @@
 **********************************************************************/
 #include <linux/version.h>
 #include <linux/pci.h>
-#include <linux/net_tstamp.h>
-#include <linux/if_vlan.h>
 #include <linux/firmware.h>
 #include <linux/ptp_clock_kernel.h>
 #include <net/vxlan.h>
@@ -37,6 +35,7 @@
 #include "cn66xx_regs.h"
 #include "cn66xx_device.h"
 #include "cn68xx_device.h"
+#include "cn23xx_pf_device.h"
 #include "liquidio_image.h"
 
 MODULE_AUTHOR("Cavium Networks, <support@cavium.com>");
@@ -52,11 +51,6 @@ module_param(ddr_timeout, int, 0644);
 MODULE_PARM_DESC(ddr_timeout,
                 "Number of milliseconds to wait for DDR initialization. 0 waits for ddr_timeout to be set to non-zero value before starting to check");
 
-static u32 console_bitmask;
-module_param(console_bitmask, int, 0644);
-MODULE_PARM_DESC(console_bitmask,
-                "Bitmask indicating which consoles have debug output redirected to syslog.");
-
 #define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
 
 #define INCR_INSTRQUEUE_PKT_COUNT(octeon_dev_ptr, iq_no, field, count)  \
@@ -139,7 +133,8 @@ union tx_info {
 #define OCTNIC_MAX_SG  (MAX_SKB_FRAGS)
 
 #define OCTNIC_GSO_MAX_HEADER_SIZE 128
-#define OCTNIC_GSO_MAX_SIZE (GSO_MAX_SIZE - OCTNIC_GSO_MAX_HEADER_SIZE)
+#define OCTNIC_GSO_MAX_SIZE                                                    \
+       (CN23XX_DEFAULT_INPUT_JABBER - OCTNIC_GSO_MAX_HEADER_SIZE)
 
 /** Structure of a node in list of gather components maintained by
  * NIC driver for each network device.
@@ -162,27 +157,6 @@ struct octnic_gather {
        u64 sg_dma_ptr;
 };
 
-/** This structure is used by NIC driver to store information required
- * to free the sk_buff when the packet has been fetched by Octeon.
- * Bytes offset below assume worst-case of a 64-bit system.
- */
-struct octnet_buf_free_info {
-       /** Bytes 1-8.  Pointer to network device private structure. */
-       struct lio *lio;
-
-       /** Bytes 9-16.  Pointer to sk_buff. */
-       struct sk_buff *skb;
-
-       /** Bytes 17-24.  Pointer to gather list. */
-       struct octnic_gather *g;
-
-       /** Bytes 25-32. Physical address of skb->data or gather list. */
-       u64 dptr;
-
-       /** Bytes 33-47. Piggybacked soft command, if any */
-       struct octeon_soft_command *sc;
-};
-
 struct handshake {
        struct completion init;
        struct completion started;
@@ -198,6 +172,7 @@ struct octeon_device_priv {
 };
 
 static int octeon_device_init(struct octeon_device *);
+static int liquidio_stop(struct net_device *netdev);
 static void liquidio_remove(struct pci_dev *pdev);
 static int liquidio_probe(struct pci_dev *pdev,
                          const struct pci_device_id *ent);
@@ -219,6 +194,7 @@ static void octeon_droq_bh(unsigned long pdev)
                        continue;
                reschedule |= octeon_droq_process_packets(oct, oct->droq[q_no],
                                                          MAX_PACKET_BUDGET);
+               lio_enable_irq(oct->droq[q_no], NULL);
        }
 
        if (reschedule)
@@ -252,76 +228,6 @@ static int lio_wait_for_oq_pkts(struct octeon_device *oct)
        return pkt_cnt;
 }
 
-void octeon_report_tx_completion_to_bql(void *txq, unsigned int pkts_compl,
-                                       unsigned int bytes_compl)
-{
-       struct netdev_queue *netdev_queue = txq;
-
-       netdev_tx_completed_queue(netdev_queue, pkts_compl, bytes_compl);
-}
-
-void octeon_update_tx_completion_counters(void *buf, int reqtype,
-                                         unsigned int *pkts_compl,
-                                         unsigned int *bytes_compl)
-{
-       struct octnet_buf_free_info *finfo;
-       struct sk_buff *skb = NULL;
-       struct octeon_soft_command *sc;
-
-       switch (reqtype) {
-       case REQTYPE_NORESP_NET:
-       case REQTYPE_NORESP_NET_SG:
-               finfo = buf;
-               skb = finfo->skb;
-               break;
-
-       case REQTYPE_RESP_NET_SG:
-       case REQTYPE_RESP_NET:
-               sc = buf;
-               skb = sc->callback_arg;
-               break;
-
-       default:
-               return;
-       }
-
-       (*pkts_compl)++;
-       *bytes_compl += skb->len;
-}
-
-void octeon_report_sent_bytes_to_bql(void *buf, int reqtype)
-{
-       struct octnet_buf_free_info *finfo;
-       struct sk_buff *skb;
-       struct octeon_soft_command *sc;
-       struct netdev_queue *txq;
-
-       switch (reqtype) {
-       case REQTYPE_NORESP_NET:
-       case REQTYPE_NORESP_NET_SG:
-               finfo = buf;
-               skb = finfo->skb;
-               break;
-
-       case REQTYPE_RESP_NET_SG:
-       case REQTYPE_RESP_NET:
-               sc = buf;
-               skb = sc->callback_arg;
-               break;
-
-       default:
-               return;
-       }
-
-       txq = netdev_get_tx_queue(skb->dev, skb_get_queue_mapping(skb));
-       netdev_tx_sent_queue(txq, skb->len);
-}
-
-int octeon_console_debug_enabled(u32 console)
-{
-       return (console_bitmask >> (console)) & 0x1;
-}
-
 /**
  * \brief Forces all IO queues off on a given device
  * @param oct Pointer to Octeon device
@@ -570,6 +476,9 @@ static const struct pci_device_id liquidio_pci_tbl[] = {
        {       /* 66xx */
                PCI_VENDOR_ID_CAVIUM, 0x92, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0
        },
+       {       /* 23xx pf */
+               PCI_VENDOR_ID_CAVIUM, 0x9702, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0
+       },
        {
                0, 0, 0, 0, 0, 0, 0
        }
@@ -587,7 +496,6 @@ static struct pci_driver liquidio_pci_driver = {
        .suspend        = liquidio_suspend,
        .resume         = liquidio_resume,
 #endif
-
 };
 
 /**
@@ -1417,6 +1325,12 @@ static int octeon_chip_specific_setup(struct octeon_device *oct)
                s = "CN66XX";
                break;
 
+       case OCTEON_CN23XX_PCIID_PF:
+               oct->chip_id = OCTEON_CN23XX_PF_VID;
+               ret = setup_cn23xx_octeon_pf_device(oct);
+               s = "CN23XX";
+               break;
+
        default:
                s = "?";
                dev_err(&oct->pci_dev->dev, "Unknown device found (dev_id: %x)\n",
@@ -2173,17 +2087,15 @@ static inline int setup_io_queues(struct octeon_device *octeon_dev,
                                                   lio->ifidx), NULL);
                if (retval) {
                        dev_err(&octeon_dev->pci_dev->dev,
-                               " %s : Runtime DROQ(RxQ) creation failed.\n",
+                               "%s : Runtime DROQ(RxQ) creation failed.\n",
                                __func__);
                        return 1;
                }
 
                droq = octeon_dev->droq[q_no];
                napi = &droq->napi;
-               dev_dbg(&octeon_dev->pci_dev->dev,
-                       "netif_napi_add netdev:%llx oct:%llx\n",
-                       (u64)netdev,
-                       (u64)octeon_dev);
+               dev_dbg(&octeon_dev->pci_dev->dev, "netif_napi_add netdev:%llx oct:%llx pf_num:%d\n",
+                       (u64)netdev, (u64)octeon_dev, octeon_dev->pf_num);
                netif_napi_add(netdev, napi, liquidio_napi_poll, 64);
 
                /* designate a CPU for this droq */
@@ -2340,143 +2252,6 @@ static int liquidio_stop(struct net_device *netdev)
        return 0;
 }
 
-void liquidio_link_ctrl_cmd_completion(void *nctrl_ptr)
-{
-       struct octnic_ctrl_pkt *nctrl = (struct octnic_ctrl_pkt *)nctrl_ptr;
-       struct net_device *netdev = (struct net_device *)nctrl->netpndev;
-       struct lio *lio = GET_LIO(netdev);
-       struct octeon_device *oct = lio->oct_dev;
-       u8 *mac;
-
-       switch (nctrl->ncmd.s.cmd) {
-       case OCTNET_CMD_CHANGE_DEVFLAGS:
-       case OCTNET_CMD_SET_MULTI_LIST:
-               break;
-
-       case OCTNET_CMD_CHANGE_MACADDR:
-               mac = ((u8 *)&nctrl->udd[0]) + 2;
-               netif_info(lio, probe, lio->netdev,
-                          "%s %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
-                          "MACAddr changed to", mac[0], mac[1],
-                          mac[2], mac[3], mac[4], mac[5]);
-               break;
-
-       case OCTNET_CMD_CHANGE_MTU:
-               /* If command is successful, change the MTU. */
-               netif_info(lio, probe, lio->netdev, " MTU Changed from %d to %d\n",
-                          netdev->mtu, nctrl->ncmd.s.param1);
-               dev_info(&oct->pci_dev->dev, "%s MTU Changed from %d to %d\n",
-                        netdev->name, netdev->mtu,
-                        nctrl->ncmd.s.param1);
-               rtnl_lock();
-               netdev->mtu = nctrl->ncmd.s.param1;
-               call_netdevice_notifiers(NETDEV_CHANGEMTU, netdev);
-               rtnl_unlock();
-               break;
-
-       case OCTNET_CMD_GPIO_ACCESS:
-               netif_info(lio, probe, lio->netdev, "LED Flashing visual identification\n");
-
-               break;
-
-       case OCTNET_CMD_LRO_ENABLE:
-               dev_info(&oct->pci_dev->dev, "%s LRO Enabled\n", netdev->name);
-               break;
-
-       case OCTNET_CMD_LRO_DISABLE:
-               dev_info(&oct->pci_dev->dev, "%s LRO Disabled\n",
-                        netdev->name);
-               break;
-
-       case OCTNET_CMD_VERBOSE_ENABLE:
-               dev_info(&oct->pci_dev->dev, "%s LRO Enabled\n", netdev->name);
-               break;
-
-       case OCTNET_CMD_VERBOSE_DISABLE:
-               dev_info(&oct->pci_dev->dev, "%s LRO Disabled\n",
-                        netdev->name);
-               break;
-
-       case OCTNET_CMD_ENABLE_VLAN_FILTER:
-               dev_info(&oct->pci_dev->dev, "%s VLAN filter enabled\n",
-                        netdev->name);
-               break;
-
-       case OCTNET_CMD_ADD_VLAN_FILTER:
-               dev_info(&oct->pci_dev->dev, "%s VLAN filter %d added\n",
-                        netdev->name, nctrl->ncmd.s.param1);
-               break;
-
-       case OCTNET_CMD_DEL_VLAN_FILTER:
-               dev_info(&oct->pci_dev->dev, "%s VLAN filter %d removed\n",
-                        netdev->name, nctrl->ncmd.s.param1);
-               break;
-
-       case OCTNET_CMD_SET_SETTINGS:
-               dev_info(&oct->pci_dev->dev, "%s settings changed\n",
-                        netdev->name);
-
-               break;
-               /* Case to handle "OCTNET_CMD_TNL_RX_CSUM_CTL"
-                * Command passed by NIC driver
-                */
-       case OCTNET_CMD_TNL_RX_CSUM_CTL:
-               if (nctrl->ncmd.s.param1 == OCTNET_CMD_RXCSUM_ENABLE) {
-                       netif_info(lio, probe, lio->netdev,
-                                  "%s RX Checksum Offload Enabled\n",
-                                  netdev->name);
-               } else if (nctrl->ncmd.s.param1 ==
-                          OCTNET_CMD_RXCSUM_DISABLE) {
-                       netif_info(lio, probe, lio->netdev,
-                                  "%s RX Checksum Offload Disabled\n",
-                                  netdev->name);
-               }
-               break;
-
-               /* Case to handle "OCTNET_CMD_TNL_TX_CSUM_CTL"
-                * Command passed by NIC driver
-                */
-       case OCTNET_CMD_TNL_TX_CSUM_CTL:
-               if (nctrl->ncmd.s.param1 == OCTNET_CMD_TXCSUM_ENABLE) {
-                       netif_info(lio, probe, lio->netdev,
-                                  "%s TX Checksum Offload Enabled\n",
-                                  netdev->name);
-               } else if (nctrl->ncmd.s.param1 ==
-                          OCTNET_CMD_TXCSUM_DISABLE) {
-                       netif_info(lio, probe, lio->netdev,
-                                  "%s TX Checksum Offload Disabled\n",
-                                  netdev->name);
-               }
-               break;
-
-               /* Case to handle "OCTNET_CMD_VXLAN_PORT_CONFIG"
-                * Command passed by NIC driver
-                */
-       case OCTNET_CMD_VXLAN_PORT_CONFIG:
-               if (nctrl->ncmd.s.more == OCTNET_CMD_VXLAN_PORT_ADD) {
-                       netif_info(lio, probe, lio->netdev,
-                                  "%s VxLAN Destination UDP PORT:%d ADDED\n",
-                                  netdev->name,
-                                  nctrl->ncmd.s.param1);
-               } else if (nctrl->ncmd.s.more ==
-                          OCTNET_CMD_VXLAN_PORT_DEL) {
-                       netif_info(lio, probe, lio->netdev,
-                                  "%s VxLAN Destination UDP PORT:%d DELETED\n",
-                                  netdev->name,
-                                  nctrl->ncmd.s.param1);
-               }
-               break;
-
-       case OCTNET_CMD_SET_FLOW_CTL:
-               netif_info(lio, probe, lio->netdev, "Set RX/TX flow control parameters\n");
-               break;
-
-       default:
-               dev_err(&oct->pci_dev->dev, "%s Unknown cmd %d\n", __func__,
-                       nctrl->ncmd.s.cmd);
-       }
-}
-
 /**
  * \brief Converts a mask based on net device flags
  * @param netdev network device
@@ -2817,8 +2592,7 @@ static void handle_timestamp(struct octeon_device *oct,
  */
 static inline int send_nic_timestamp_pkt(struct octeon_device *oct,
                                         struct octnic_data_pkt *ndata,
-                                        struct octnet_buf_free_info *finfo,
-                                        int xmit_more)
+                                        struct octnet_buf_free_info *finfo)
 {
        int retval;
        struct octeon_soft_command *sc;
@@ -2848,7 +2622,7 @@ static inline int send_nic_timestamp_pkt(struct octeon_device *oct,
 
        len = (u32)((struct octeon_instr_ih2 *)(&sc->cmd.cmd2.ih2))->dlengsz;
 
-       ring_doorbell = !xmit_more;
+       ring_doorbell = 1;
        retval = octeon_send_command(oct, sc->iq_no, ring_doorbell, &sc->cmd,
                                     sc, len, ndata->reqtype);
 
@@ -2881,7 +2655,7 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
        union tx_info *tx_info;
        int status = 0;
        int q_idx = 0, iq_no = 0;
-       int xmit_more, j;
+       int j;
        u64 dptr = 0;
        u32 tag = 0;
 
@@ -3077,12 +2851,10 @@ static int liquidio_xmit(struct sk_buff *skb, struct net_device *netdev)
                irh->vlan = skb_vlan_tag_get(skb) & 0xfff;
        }
 
-       xmit_more = skb->xmit_more;
-
        if (unlikely(cmdsetup.s.timestamp))
-               status = send_nic_timestamp_pkt(oct, &ndata, finfo, xmit_more);
+               status = send_nic_timestamp_pkt(oct, &ndata, finfo);
        else
-               status = octnet_send_nic_data_pkt(oct, &ndata, xmit_more);
+               status = octnet_send_nic_data_pkt(oct, &ndata);
        if (status == IQ_SEND_FAILED)
                goto lio_xmit_failed;
 
@@ -3190,8 +2962,8 @@ static int liquidio_vlan_rx_kill_vid(struct net_device *netdev,
  *                              OCTNET_CMD_RXCSUM_DISABLE
  * @returns                     SUCCESS or FAILURE
  */
-int liquidio_set_rxcsum_command(struct net_device *netdev, int command,
-                               u8 rx_cmd)
+static int liquidio_set_rxcsum_command(struct net_device *netdev, int command,
+                                      u8 rx_cmd)
 {
        struct lio *lio = GET_LIO(netdev);
        struct octeon_device *oct = lio->oct_dev;
@@ -3249,31 +3021,6 @@ static int liquidio_vxlan_port_command(struct net_device *netdev, int command,
        return ret;
 }
 
-int liquidio_set_feature(struct net_device *netdev, int cmd, u16 param1)
-{
-       struct lio *lio = GET_LIO(netdev);
-       struct octeon_device *oct = lio->oct_dev;
-       struct octnic_ctrl_pkt nctrl;
-       int ret = 0;
-
-       memset(&nctrl, 0, sizeof(struct octnic_ctrl_pkt));
-
-       nctrl.ncmd.u64 = 0;
-       nctrl.ncmd.s.cmd = cmd;
-       nctrl.ncmd.s.param1 = param1;
-       nctrl.iq_no = lio->linfo.txpciq[0].s.q_no;
-       nctrl.wait_time = 100;
-       nctrl.netpndev = (u64)netdev;
-       nctrl.cb_fn = liquidio_link_ctrl_cmd_completion;
-
-       ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl);
-       if (ret < 0) {
-               dev_err(&oct->pci_dev->dev, "Feature change failed in core (ret: 0x%x)\n",
-                       ret);
-       }
-       return ret;
-}
-
 /** \brief Net device fix features
  * @param netdev  pointer to network device
  * @param request features requested
@@ -3492,8 +3239,9 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
        union oct_nic_if_cfg if_cfg;
        unsigned int base_queue;
        unsigned int gmx_port_id;
-       u32 resp_size, ctx_size;
+       u32 resp_size, ctx_size, data_size;
        u32 ifidx_or_pfnum;
+       struct lio_version *vdata;
 
        /* This is to handle link status changes */
        octeon_register_dispatch_fn(octeon_dev, OPCODE_NIC,
@@ -3515,21 +3263,37 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
        for (i = 0; i < octeon_dev->ifcount; i++) {
                resp_size = sizeof(struct liquidio_if_cfg_resp);
                ctx_size = sizeof(struct liquidio_if_cfg_context);
+               data_size = sizeof(struct lio_version);
                sc = (struct octeon_soft_command *)
-                       octeon_alloc_soft_command(octeon_dev, 0,
+                       octeon_alloc_soft_command(octeon_dev, data_size,
                                                  resp_size, ctx_size);
                resp = (struct liquidio_if_cfg_resp *)sc->virtrptr;
                ctx  = (struct liquidio_if_cfg_context *)sc->ctxptr;
+               vdata = (struct lio_version *)sc->virtdptr;
 
-               num_iqueues =
-                       CFG_GET_NUM_TXQS_NIC_IF(octeon_get_conf(octeon_dev), i);
-               num_oqueues =
-                       CFG_GET_NUM_RXQS_NIC_IF(octeon_get_conf(octeon_dev), i);
-               base_queue =
-                       CFG_GET_BASE_QUE_NIC_IF(octeon_get_conf(octeon_dev), i);
-               gmx_port_id =
-                       CFG_GET_GMXID_NIC_IF(octeon_get_conf(octeon_dev), i);
-               ifidx_or_pfnum = i;
+               *((u64 *)vdata) = 0;
+               vdata->major = cpu_to_be16(LIQUIDIO_BASE_MAJOR_VERSION);
+               vdata->minor = cpu_to_be16(LIQUIDIO_BASE_MINOR_VERSION);
+               vdata->micro = cpu_to_be16(LIQUIDIO_BASE_MICRO_VERSION);
+
+               if (OCTEON_CN23XX_PF(octeon_dev)) {
+                       num_iqueues = octeon_dev->sriov_info.num_pf_rings;
+                       num_oqueues = octeon_dev->sriov_info.num_pf_rings;
+                       base_queue = octeon_dev->sriov_info.pf_srn;
+
+                       gmx_port_id = octeon_dev->pf_num;
+                       ifidx_or_pfnum = octeon_dev->pf_num;
+               } else {
+                       num_iqueues = CFG_GET_NUM_TXQS_NIC_IF(
+                                               octeon_get_conf(octeon_dev), i);
+                       num_oqueues = CFG_GET_NUM_RXQS_NIC_IF(
+                                               octeon_get_conf(octeon_dev), i);
+                       base_queue = CFG_GET_BASE_QUE_NIC_IF(
+                                               octeon_get_conf(octeon_dev), i);
+                       gmx_port_id = CFG_GET_GMXID_NIC_IF(
+                                               octeon_get_conf(octeon_dev), i);
+                       ifidx_or_pfnum = i;
+               }
 
                dev_dbg(&octeon_dev->pci_dev->dev,
                        "requesting config for interface %d, iqs %d, oqs %d\n",
@@ -3633,12 +3397,16 @@ static int setup_nic_devices(struct octeon_device *octeon_dev)
 
                lio->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
 
-               lio->dev_capability = NETIF_F_HIGHDMA
-                               | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM
-                               | NETIF_F_SG | NETIF_F_RXCSUM
-                               | NETIF_F_GRO
-                               | NETIF_F_TSO | NETIF_F_TSO6
-                               | NETIF_F_LRO;
+               if (OCTEON_CN23XX_PF(octeon_dev) ||
+                   OCTEON_CN6XXX(octeon_dev)) {
+                       lio->dev_capability = NETIF_F_HIGHDMA
+                                             | NETIF_F_IP_CSUM
+                                             | NETIF_F_IPV6_CSUM
+                                             | NETIF_F_SG | NETIF_F_RXCSUM
+                                             | NETIF_F_GRO
+                                             | NETIF_F_TSO | NETIF_F_TSO6
+                                             | NETIF_F_LRO;
+               }
                netif_set_gso_max_size(netdev, OCTNIC_GSO_MAX_SIZE);
 
                /*  Copy of transmit encapsulation capabilities:
@@ -3925,6 +3693,22 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
 
        octeon_set_io_queues_off(octeon_dev);
 
+       if (OCTEON_CN23XX_PF(octeon_dev)) {
+               ret = octeon_dev->fn_list.setup_device_regs(octeon_dev);
+               if (ret) {
+                       dev_err(&octeon_dev->pci_dev->dev, "OCTEON: Failed to configure device registers\n");
+                       return ret;
+               }
+       }
+
+       /* Initialize soft command buffer pool
+        */
+       if (octeon_setup_sc_buffer_pool(octeon_dev)) {
+               dev_err(&octeon_dev->pci_dev->dev, "sc buffer pool allocation failed\n");
+               return 1;
+       }
+       atomic_set(&octeon_dev->status, OCT_DEV_SC_BUFF_POOL_INIT_DONE);
+
        /*  Setup the data structures that manage this Octeon's Input queues. */
        if (octeon_setup_instr_queues(octeon_dev)) {
                dev_err(&octeon_dev->pci_dev->dev,
@@ -3936,14 +3720,6 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
        }
        atomic_set(&octeon_dev->status, OCT_DEV_INSTR_QUEUE_INIT_DONE);
 
-       /* Initialize soft command buffer pool
-        */
-       if (octeon_setup_sc_buffer_pool(octeon_dev)) {
-               dev_err(&octeon_dev->pci_dev->dev, "sc buffer pool allocation failed\n");
-               return 1;
-       }
-       atomic_set(&octeon_dev->status, OCT_DEV_SC_BUFF_POOL_INIT_DONE);
-
        /* Initialize lists to manage the requests of different types that
         * arrive from user & kernel applications for this octeon device.
         */
@@ -3988,7 +3764,11 @@ static int octeon_device_init(struct octeon_device *octeon_dev)
        octeon_dev->fn_list.enable_interrupt(octeon_dev->chip);
 
        /* Enable the input and output queues for this Octeon device */
-       octeon_dev->fn_list.enable_io_queues(octeon_dev);
+       ret = octeon_dev->fn_list.enable_io_queues(octeon_dev);
+       if (ret) {
+               dev_err(&octeon_dev->pci_dev->dev, "Failed to enable input/output queues");
+               return ret;
+       }
 
        atomic_set(&octeon_dev->status, OCT_DEV_IO_QUEUES_DONE);