diff --git a/drivers/net/cxgbe/base/adapter.h b/drivers/net/cxgbe/base/adapter.h
index 3e74177f2..f9c4cde84 100644
--- a/drivers/net/cxgbe/base/adapter.h
+++ b/drivers/net/cxgbe/base/adapter.h
@@ -19,7 +19,6 @@
 #include "t4_regs_values.h"
 
 enum {
-	MAX_ETH_QSETS = 64,           /* # of Ethernet Tx/Rx queue sets */
 	MAX_CTRL_QUEUES = NCHAN,      /* # of control Tx queues */
 };
 
@@ -47,9 +46,10 @@ struct port_info {
 	u8     pidx;			/* port index for this PF */
 	u8     tx_chan;                 /* associated channel */
 
-	u8     n_rx_qsets;              /* # of rx qsets */
-	u8     n_tx_qsets;              /* # of tx qsets */
-	u8     first_qset;              /* index of first qset */
+	u16    n_rx_qsets;              /* # of rx qsets */
+	u16    n_tx_qsets;              /* # of tx qsets */
+	u16    first_rxqset;            /* index of first rxqset */
+	u16    first_txqset;            /* index of first txqset */
 
 	u16    *rss;                    /* rss table */
 	u8     rss_mode;                /* rss mode */
@@ -274,8 +274,8 @@ struct sge_ctrl_txq {                /* State for an SGE control Tx queue */
 } __rte_cache_aligned;
 
 struct sge {
-	struct sge_eth_txq ethtxq[MAX_ETH_QSETS];
-	struct sge_eth_rxq ethrxq[MAX_ETH_QSETS];
+	struct sge_eth_txq *ethtxq;
+	struct sge_eth_rxq *ethrxq;
 	struct sge_rspq fw_evtq __rte_cache_aligned;
 	struct sge_ctrl_txq ctrlq[MAX_CTRL_QUEUES];
 
diff --git a/drivers/net/cxgbe/base/common.h b/drivers/net/cxgbe/base/common.h
index 79c8fcb76..07508a186 100644
--- a/drivers/net/cxgbe/base/common.h
+++ b/drivers/net/cxgbe/base/common.h
@@ -218,6 +218,7 @@ struct rss_params {
  */
 struct pf_resources {
 	unsigned int neq;      /* N egress Qs */
+	unsigned int nethctrl; /* N egress ETH or CTRL Qs */
 	unsigned int niqflint; /* N ingress Qs/w free list(s) & intr */
 };
 
diff --git a/drivers/net/cxgbe/base/t4_hw.c b/drivers/net/cxgbe/base/t4_hw.c
index c8514c963..943d94fad 100644
--- a/drivers/net/cxgbe/base/t4_hw.c
+++ b/drivers/net/cxgbe/base/t4_hw.c
@@ -2517,6 +2517,10 @@ int t4_get_pfres(struct adapter *adapter)
 
 	word = be32_to_cpu(rpl.type_to_neq);
 	pfres->neq = G_FW_PFVF_CMD_NEQ(word);
+
+	word = be32_to_cpu(rpl.r_caps_to_nethctrl);
+	pfres->nethctrl = G_FW_PFVF_CMD_NETHCTRL(word);
+
 	return 0;
 }
 
diff --git a/drivers/net/cxgbe/cxgbe.h b/drivers/net/cxgbe/cxgbe.h
index 0bf6061c0..ef62af1c3 100644
--- a/drivers/net/cxgbe/cxgbe.h
+++ b/drivers/net/cxgbe/cxgbe.h
@@ -98,7 +98,8 @@ int cxgbe_poll_for_completion(struct sge_rspq *q, unsigned int us,
 int cxgbe_link_start(struct port_info *pi);
 int cxgbe_setup_sge_fwevtq(struct adapter *adapter);
 int cxgbe_setup_sge_ctrl_txq(struct adapter *adapter);
-void cxgbe_cfg_queues(struct rte_eth_dev *eth_dev);
+int cxgbe_cfg_queues(struct rte_eth_dev *eth_dev);
+void cxgbe_cfg_queues_free(struct adapter *adapter);
 int cxgbe_cfg_queue_count(struct rte_eth_dev *eth_dev);
 int cxgbe_init_rss(struct adapter *adap);
 int cxgbe_setup_rss(struct port_info *pi);
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index 38b43772c..329b7cb5a 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -116,7 +116,6 @@ int cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 {
 	struct port_info *pi = eth_dev->data->dev_private;
 	struct adapter *adapter = pi->adapter;
-	int max_queues = adapter->sge.max_ethqsets / adapter->params.nports;
 
 	static const struct rte_eth_desc_lim cxgbe_desc_lim = {
 		.nb_max = CXGBE_MAX_RING_DESC_SIZE,
@@ -126,8 +125,8 @@ int cxgbe_dev_info_get(struct rte_eth_dev *eth_dev,
 
 	device_info->min_rx_bufsize = CXGBE_MIN_RX_BUFSIZE;
 	device_info->max_rx_pktlen = CXGBE_MAX_RX_PKTLEN;
-	device_info->max_rx_queues = max_queues;
-	device_info->max_tx_queues = max_queues;
+	device_info->max_rx_queues = adapter->sge.max_ethqsets;
+	device_info->max_tx_queues = adapter->sge.max_ethqsets;
 	device_info->max_mac_addrs = 1;
 	/* XXX: For now we support one MAC/port */
 	device_info->max_vfs = adapter->params.arch.vfcount;
@@ -501,13 +500,14 @@ int cxgbe_dev_tx_queue_setup(struct rte_eth_dev *eth_dev,
 	struct port_info *pi = eth_dev->data->dev_private;
 	struct adapter *adapter = pi->adapter;
 	struct sge *s = &adapter->sge;
-	struct sge_eth_txq *txq = &s->ethtxq[pi->first_qset + queue_idx];
-	int err = 0;
 	unsigned int temp_nb_desc;
+	struct sge_eth_txq *txq;
+	int err = 0;
 
+	txq = &s->ethtxq[pi->first_txqset + queue_idx];
 	dev_debug(adapter, "%s: eth_dev->data->nb_tx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; pi->first_qset = %u\n",
 		  __func__, eth_dev->data->nb_tx_queues, queue_idx, nb_desc,
-		  socket_id, pi->first_qset);
+		  socket_id, pi->first_txqset);
 
 	/*  Free up the existing queue  */
 	if (eth_dev->data->tx_queues[queue_idx]) {
@@ -603,16 +603,16 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 			     const struct rte_eth_rxconf *rx_conf __rte_unused,
 			     struct rte_mempool *mp)
 {
+	unsigned int pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
 	struct port_info *pi = eth_dev->data->dev_private;
 	struct adapter *adapter = pi->adapter;
+	struct rte_eth_dev_info dev_info;
 	struct sge *s = &adapter->sge;
-	struct sge_eth_rxq *rxq = &s->ethrxq[pi->first_qset + queue_idx];
-	int err = 0;
-	int msi_idx = 0;
 	unsigned int temp_nb_desc;
-	struct rte_eth_dev_info dev_info;
-	unsigned int pkt_len = eth_dev->data->dev_conf.rxmode.max_rx_pkt_len;
+	int err = 0, msi_idx = 0;
+	struct sge_eth_rxq *rxq;
 
+	rxq = &s->ethrxq[pi->first_rxqset + queue_idx];
 	dev_debug(adapter, "%s: eth_dev->data->nb_rx_queues = %d; queue_idx = %d; nb_desc = %d; socket_id = %d; mp = %p\n",
 		  __func__, eth_dev->data->nb_rx_queues, queue_idx, nb_desc,
 		  socket_id, mp);
@@ -685,11 +685,10 @@ int cxgbe_dev_rx_queue_setup(struct rte_eth_dev *eth_dev,
 void cxgbe_dev_rx_queue_release(void *q)
 {
 	struct sge_eth_rxq *rxq = (struct sge_eth_rxq *)q;
-	struct sge_rspq *rq = &rxq->rspq;
 
-	if (rq) {
+	if (rxq) {
 		struct port_info *pi = (struct port_info *)
-				       (rq->eth_dev->data->dev_private);
+				       (rxq->rspq.eth_dev->data->dev_private);
 		struct adapter *adap = pi->adapter;
 
 		dev_debug(adapter, "%s: pi->port_id = %d; rx_queue_id = %d\n",
@@ -729,7 +728,7 @@ static int cxgbe_dev_stats_get(struct rte_eth_dev *eth_dev,
 
 	for (i = 0; i < pi->n_rx_qsets; i++) {
 		struct sge_eth_rxq *rxq =
-			&s->ethrxq[pi->first_qset + i];
+			&s->ethrxq[pi->first_rxqset + i];
 
 		eth_stats->q_ipackets[i] = rxq->stats.pkts;
 		eth_stats->q_ibytes[i] = rxq->stats.rx_bytes;
@@ -739,7 +738,7 @@ static int cxgbe_dev_stats_get(struct rte_eth_dev *eth_dev,
 
 	for (i = 0; i < pi->n_tx_qsets; i++) {
 		struct sge_eth_txq *txq =
-			&s->ethtxq[pi->first_qset + i];
+			&s->ethtxq[pi->first_txqset + i];
 
 		eth_stats->q_opackets[i] = txq->stats.pkts;
 		eth_stats->q_obytes[i] = txq->stats.tx_bytes;
@@ -760,14 +759,14 @@ static int cxgbe_dev_stats_reset(struct rte_eth_dev *eth_dev)
 	cxgbe_stats_reset(pi);
 	for (i = 0; i < pi->n_rx_qsets; i++) {
 		struct sge_eth_rxq *rxq =
-			&s->ethrxq[pi->first_qset + i];
+			&s->ethrxq[pi->first_rxqset + i];
 
 		rxq->stats.pkts = 0;
 		rxq->stats.rx_bytes = 0;
 	}
 	for (i = 0; i < pi->n_tx_qsets; i++) {
 		struct sge_eth_txq *txq =
-			&s->ethtxq[pi->first_qset + i];
+			&s->ethtxq[pi->first_txqset + i];
 
 		txq->stats.pkts = 0;
 		txq->stats.tx_bytes = 0;
diff --git a/drivers/net/cxgbe/cxgbe_filter.c b/drivers/net/cxgbe/cxgbe_filter.c
index 384dde3f9..5a7efe7a7 100644
--- a/drivers/net/cxgbe/cxgbe_filter.c
+++ b/drivers/net/cxgbe/cxgbe_filter.c
@@ -145,7 +145,7 @@ static unsigned int get_filter_steerq(struct rte_eth_dev *dev,
 		 * then assume it is an absolute qid.
 		 */
 		if (fs->iq < pi->n_rx_qsets)
-			iq = adapter->sge.ethrxq[pi->first_qset +
+			iq = adapter->sge.ethrxq[pi->first_rxqset +
 						 fs->iq].rspq.abs_id;
 		else
 			iq = fs->iq;
diff --git a/drivers/net/cxgbe/cxgbe_main.c b/drivers/net/cxgbe/cxgbe_main.c
index d0a64229c..da4ae25d4 100644
--- a/drivers/net/cxgbe/cxgbe_main.c
+++ b/drivers/net/cxgbe/cxgbe_main.c
@@ -526,22 +526,6 @@ static int tid_init(struct tid_info *t)
 	return 0;
 }
 
-static inline bool is_x_1g_port(const struct link_config *lc)
-{
-	return (lc->pcaps & FW_PORT_CAP32_SPEED_1G) != 0;
-}
-
-static inline bool is_x_10g_port(const struct link_config *lc)
-{
-	unsigned int speeds, high_speeds;
-
-	speeds = V_FW_PORT_CAP32_SPEED(G_FW_PORT_CAP32_SPEED(lc->pcaps));
-	high_speeds = speeds &
-		      ~(FW_PORT_CAP32_SPEED_100M | FW_PORT_CAP32_SPEED_1G);
-
-	return high_speeds != 0;
-}
-
 static inline void init_rspq(struct adapter *adap, struct sge_rspq *q,
 		      unsigned int us, unsigned int cnt,
 		      unsigned int size, unsigned int iqe_size)
@@ -554,20 +538,35 @@ static inline void init_rspq(struct adapter *adap, struct sge_rspq *q,
 
 int cxgbe_cfg_queue_count(struct rte_eth_dev *eth_dev)
 {
-	struct port_info *pi = eth_dev->data->dev_private;
+	struct port_info *temp_pi, *pi = eth_dev->data->dev_private;
 	struct adapter *adap = pi->adapter;
+	u16 first_txq = 0, first_rxq = 0;
 	struct sge *s = &adap->sge;
-	unsigned int max_queues = s->max_ethqsets / adap->params.nports;
+	u16 i, max_rxqs, max_txqs;
+
+	max_rxqs = s->max_ethqsets;
+	max_txqs = s->max_ethqsets;
+	for_each_port(adap, i) {
+		temp_pi = adap2pinfo(adap, i);
+		if (i == pi->port_id)
+			break;
+
+		if (max_rxqs <= temp_pi->n_rx_qsets ||
+		    max_txqs <= temp_pi->n_tx_qsets)
+			return -ENOMEM;
+
+		first_rxq += temp_pi->n_rx_qsets;
+		first_txq += temp_pi->n_tx_qsets;
+		max_rxqs -= temp_pi->n_rx_qsets;
+		max_txqs -= temp_pi->n_tx_qsets;
+	}
 
 	if ((eth_dev->data->nb_rx_queues < 1) ||
 	    (eth_dev->data->nb_tx_queues < 1))
 		return -EINVAL;
 
-	if ((eth_dev->data->nb_rx_queues > max_queues) ||
-	    (eth_dev->data->nb_tx_queues > max_queues))
-		return -EINVAL;
-
-	if (eth_dev->data->nb_rx_queues > pi->rss_size)
+	if (eth_dev->data->nb_rx_queues > max_rxqs ||
+	    eth_dev->data->nb_tx_queues > max_txqs)
 		return -EINVAL;
 
 	/* We must configure RSS, since config has changed*/
@@ -575,68 +574,66 @@ int cxgbe_cfg_queue_count(struct rte_eth_dev *eth_dev)
 
 	pi->n_rx_qsets = eth_dev->data->nb_rx_queues;
 	pi->n_tx_qsets = eth_dev->data->nb_tx_queues;
+	pi->first_rxqset = first_rxq;
+	pi->first_txqset = first_txq;
 
 	return 0;
 }
 
-void cxgbe_cfg_queues(struct rte_eth_dev *eth_dev)
+void cxgbe_cfg_queues_free(struct adapter *adap)
+{
+	if (adap->sge.ethtxq) {
+		rte_free(adap->sge.ethtxq);
+		adap->sge.ethtxq = NULL;
+	}
+
+	if (adap->sge.ethrxq) {
+		rte_free(adap->sge.ethrxq);
+		adap->sge.ethrxq = NULL;
+	}
+
+	adap->flags &= ~CFG_QUEUES;
+}
+
+int cxgbe_cfg_queues(struct rte_eth_dev *eth_dev)
 {
 	struct port_info *pi = eth_dev->data->dev_private;
 	struct adapter *adap = pi->adapter;
 	struct sge *s = &adap->sge;
-	unsigned int i, nb_ports = 0, qidx = 0;
-	unsigned int q_per_port = 0;
+	u16 i;
 
 	if (!(adap->flags & CFG_QUEUES)) {
-		for_each_port(adap, i) {
-			struct port_info *tpi = adap2pinfo(adap, i);
-
-			nb_ports += (is_x_10g_port(&tpi->link_cfg)) ||
-				     is_x_1g_port(&tpi->link_cfg) ? 1 : 0;
-		}
-
-		/*
-		 * We default up to # of cores queues per 1G/10G port.
-		 */
-		if (nb_ports)
-			q_per_port = (s->max_ethqsets -
-				     (adap->params.nports - nb_ports)) /
-				     nb_ports;
-
-		if (q_per_port > rte_lcore_count())
-			q_per_port = rte_lcore_count();
-
-		for_each_port(adap, i) {
-			struct port_info *pi = adap2pinfo(adap, i);
-
-			pi->first_qset = qidx;
-
-			/* Initially n_rx_qsets == n_tx_qsets */
-			pi->n_rx_qsets = (is_x_10g_port(&pi->link_cfg) ||
-					  is_x_1g_port(&pi->link_cfg)) ?
-					  q_per_port : 1;
-			pi->n_tx_qsets = pi->n_rx_qsets;
-
-			if (pi->n_rx_qsets > pi->rss_size)
-				pi->n_rx_qsets = pi->rss_size;
+		s->ethrxq = rte_calloc_socket(NULL, s->max_ethqsets,
+					      sizeof(struct sge_eth_rxq), 0,
+					      rte_socket_id());
+		if (!s->ethrxq)
+			return -ENOMEM;
 
-			qidx += pi->n_rx_qsets;
+		s->ethtxq = rte_calloc_socket(NULL, s->max_ethqsets,
+					      sizeof(struct sge_eth_txq), 0,
+					      rte_socket_id());
+		if (!s->ethtxq) {
+			rte_free(s->ethrxq);
+			s->ethrxq = NULL;
+			return -ENOMEM;
 		}
 
-		for (i = 0; i < ARRAY_SIZE(s->ethrxq); i++) {
+		for (i = 0; i < s->max_ethqsets; i++) {
 			struct sge_eth_rxq *r = &s->ethrxq[i];
+			struct sge_eth_txq *t = &s->ethtxq[i];
 
 			init_rspq(adap, &r->rspq, 5, 32, 1024, 64);
 			r->usembufs = 1;
 			r->fl.size = (r->usembufs ? 1024 : 72);
-		}
 
-		for (i = 0; i < ARRAY_SIZE(s->ethtxq); i++)
-			s->ethtxq[i].q.size = 1024;
+			t->q.size = 1024;
+		}
 
 		init_rspq(adap, &adap->sge.fw_evtq, 0, 0, 1024, 64);
 		adap->flags |= CFG_QUEUES;
 	}
+
+	return 0;
 }
 
 void cxgbe_stats_get(struct port_info *pi, struct port_stats *stats)
@@ -1043,34 +1040,31 @@ static void configure_pcie_ext_tag(struct adapter *adapter)
 /* Figure out how many Queue Sets we can support */
 void cxgbe_configure_max_ethqsets(struct adapter *adapter)
 {
-	unsigned int ethqsets;
+	unsigned int ethqsets, reserved;
 
-	/*
-	 * We need to reserve an Ingress Queue for the Asynchronous Firmware
-	 * Event Queue.
+	/* We need to reserve an Ingress Queue for the Asynchronous Firmware
+	 * Event Queue and 1 Control Queue per port.
 	 *
 	 * For each Queue Set, we'll need the ability to allocate two Egress
 	 * Contexts -- one for the Ingress Queue Free List and one for the TX
 	 * Ethernet Queue.
 	 */
+	reserved = max(adapter->params.nports, 1);
 	if (is_pf4(adapter)) {
 		struct pf_resources *pfres = &adapter->params.pfres;
 
-		ethqsets = pfres->niqflint - 1;
-		if (pfres->neq < ethqsets * 2)
+		ethqsets = min(pfres->niqflint, pfres->nethctrl);
+		if (ethqsets > (pfres->neq / 2))
 			ethqsets = pfres->neq / 2;
 	} else {
 		struct vf_resources *vfres = &adapter->params.vfres;
 
-		ethqsets = vfres->niqflint - 1;
-		if (vfres->nethctrl != ethqsets)
-			ethqsets = min(vfres->nethctrl, ethqsets);
-		if (vfres->neq < ethqsets * 2)
+		ethqsets = min(vfres->niqflint, vfres->nethctrl);
+		if (ethqsets > (vfres->neq / 2))
 			ethqsets = vfres->neq / 2;
 	}
 
-	if (ethqsets > MAX_ETH_QSETS)
-		ethqsets = MAX_ETH_QSETS;
+	ethqsets -= reserved;
 	adapter->sge.max_ethqsets = ethqsets;
 }
 
@@ -1707,7 +1701,7 @@ int cxgbe_write_rss_conf(const struct port_info *pi, uint64_t rss_hf)
 			 F_FW_RSS_VI_CONFIG_CMD_IP6FOURTUPEN |
 			 F_FW_RSS_VI_CONFIG_CMD_UDPEN;
 
-	rxq = &adapter->sge.ethrxq[pi->first_qset];
+	rxq = &adapter->sge.ethrxq[pi->first_rxqset];
 	rss = rxq[0].rspq.abs_id;
 
 	/* If Tunnel All Lookup isn't specified in the global RSS
@@ -1738,7 +1732,7 @@ int cxgbe_write_rss(const struct port_info *pi, const u16 *queues)
 	/*  Should never be called before setting up sge eth rx queues */
 	BUG_ON(!(adapter->flags & FULL_INIT_DONE));
 
-	rxq = &adapter->sge.ethrxq[pi->first_qset];
+	rxq = &adapter->sge.ethrxq[pi->first_rxqset];
 	rss = rte_zmalloc(NULL, pi->rss_size * sizeof(u16), 0);
 	if (!rss)
 		return -ENOMEM;
@@ -1810,7 +1804,7 @@ void cxgbe_enable_rx_queues(struct port_info *pi)
 	unsigned int i;
 
 	for (i = 0; i < pi->n_rx_qsets; i++)
-		enable_rx(adap, &s->ethrxq[pi->first_qset + i].rspq);
+		enable_rx(adap, &s->ethrxq[pi->first_rxqset + i].rspq);
 }
 
 /**
@@ -1988,6 +1982,8 @@ void cxgbe_close(struct adapter *adapter)
 		adapter->flags &= ~FULL_INIT_DONE;
 	}
 
+	cxgbe_cfg_queues_free(adapter);
+
 	if (is_pf4(adapter) && (adapter->flags & FW_OK))
 		t4_fw_bye(adapter, adapter->mbox);
 }
@@ -2163,7 +2159,9 @@ int cxgbe_probe(struct adapter *adapter)
 		}
 	}
 
-	cxgbe_cfg_queues(adapter->eth_dev);
+	err = cxgbe_cfg_queues(adapter->eth_dev);
+	if (err)
+		goto out_free;
 
 	cxgbe_print_adapter_info(adapter);
 	cxgbe_print_port_info(adapter);
@@ -2222,6 +2220,8 @@ int cxgbe_probe(struct adapter *adapter)
 	return 0;
 
 out_free:
+	cxgbe_cfg_queues_free(adapter);
+
 	for_each_port(adapter, i) {
 		pi = adap2pinfo(adapter, i);
 		if (pi->viid != 0)
diff --git a/drivers/net/cxgbe/cxgbevf_ethdev.c b/drivers/net/cxgbe/cxgbevf_ethdev.c
index b3c885d6e..947fcdd40 100644
--- a/drivers/net/cxgbe/cxgbevf_ethdev.c
+++ b/drivers/net/cxgbe/cxgbevf_ethdev.c
@@ -55,7 +55,7 @@ static int cxgbevf_dev_stats_get(struct rte_eth_dev *eth_dev,
 
 	for (i = 0; i < pi->n_rx_qsets; i++) {
 		struct sge_eth_rxq *rxq =
-			&s->ethrxq[pi->first_qset + i];
+			&s->ethrxq[pi->first_rxqset + i];
 
 		eth_stats->q_ipackets[i] = rxq->stats.pkts;
 		eth_stats->q_ibytes[i] = rxq->stats.rx_bytes;
@@ -65,7 +65,7 @@ static int cxgbevf_dev_stats_get(struct rte_eth_dev *eth_dev,
 
 	for (i = 0; i < pi->n_tx_qsets; i++) {
 		struct sge_eth_txq *txq =
-			&s->ethtxq[pi->first_qset + i];
+			&s->ethtxq[pi->first_txqset + i];
 
 		eth_stats->q_opackets[i] = txq->stats.pkts;
 		eth_stats->q_obytes[i] = txq->stats.tx_bytes;
diff --git a/drivers/net/cxgbe/cxgbevf_main.c b/drivers/net/cxgbe/cxgbevf_main.c
index 9fe0ec6f6..35d873402 100644
--- a/drivers/net/cxgbe/cxgbevf_main.c
+++ b/drivers/net/cxgbe/cxgbevf_main.c
@@ -278,7 +278,10 @@ int cxgbevf_probe(struct adapter *adapter)
 		}
 	}
 
-	cxgbe_cfg_queues(adapter->eth_dev);
+	err = cxgbe_cfg_queues(adapter->eth_dev);
+	if (err)
+		goto out_free;
+
 	cxgbe_print_adapter_info(adapter);
 	cxgbe_print_port_info(adapter);
 
@@ -293,6 +296,8 @@ int cxgbevf_probe(struct adapter *adapter)
 	return 0;
 
 out_free:
+	cxgbe_cfg_queues_free(adapter);
+
 	for_each_port(adapter, i) {
 		pi = adap2pinfo(adapter, i);
 		if (pi->viid != 0)
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 34e48574a..3aeef2e2f 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -2193,15 +2193,18 @@ static void free_rspq_fl(struct adapter *adap, struct sge_rspq *rq,
  */
 void t4_sge_eth_clear_queues(struct port_info *pi)
 {
-	int i;
 	struct adapter *adap = pi->adapter;
-	struct sge_eth_rxq *rxq = &adap->sge.ethrxq[pi->first_qset];
-	struct sge_eth_txq *txq = &adap->sge.ethtxq[pi->first_qset];
+	struct sge_eth_rxq *rxq;
+	struct sge_eth_txq *txq;
+	int i;
 
+	rxq = &adap->sge.ethrxq[pi->first_rxqset];
 	for (i = 0; i < pi->n_rx_qsets; i++, rxq++) {
 		if (rxq->rspq.desc)
 			t4_sge_eth_rxq_stop(adap, &rxq->rspq);
 	}
+
+	txq = &adap->sge.ethtxq[pi->first_txqset];
 	for (i = 0; i < pi->n_tx_qsets; i++, txq++) {
 		if (txq->q.desc) {
 			struct sge_txq *q = &txq->q;
@@ -2241,7 +2244,7 @@ void t4_sge_eth_release_queues(struct port_info *pi)
 	struct sge_eth_txq *txq;
 	unsigned int i;
 
-	rxq = &adap->sge.ethrxq[pi->first_qset];
+	rxq = &adap->sge.ethrxq[pi->first_rxqset];
 	/* clean up Ethernet Tx/Rx queues */
 	for (i = 0; i < pi->n_rx_qsets; i++, rxq++) {
 		/* Free only the queues allocated */
@@ -2253,7 +2256,7 @@ void t4_sge_eth_release_queues(struct port_info *pi)
 		}
 	}
 
-	txq = &adap->sge.ethtxq[pi->first_qset];
+	txq = &adap->sge.ethtxq[pi->first_txqset];
 	for (i = 0; i < pi->n_tx_qsets; i++, txq++) {
 		/* Free only the queues allocated */
 		if (txq->q.desc) {
