Commit 84b9000a authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'ionic-fixes'

Shannon Nelson says:

====================
ionic fixes

These are a few little fixes and cleanups found while working
on other features and more testing.
====================
parents df291e54 e768929d
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -184,6 +184,10 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int num_vfs)
	struct device *dev = ionic->dev;
	int ret = 0;

	if (ionic->lif &&
	    test_bit(IONIC_LIF_F_FW_RESET, ionic->lif->state))
		return -EBUSY;

	if (num_vfs > 0) {
		ret = pci_enable_sriov(pdev, num_vfs);
		if (ret) {
+5 −3
Original line number Diff line number Diff line
@@ -14,18 +14,20 @@
static void ionic_watchdog_cb(struct timer_list *t)
{
	struct ionic *ionic = from_timer(ionic, t, watchdog_timer);
	struct ionic_lif *lif = ionic->lif;
	int hb;

	mod_timer(&ionic->watchdog_timer,
		  round_jiffies(jiffies + ionic->watchdog_period));

	if (!ionic->lif)
	if (!lif)
		return;

	hb = ionic_heartbeat_check(ionic);

	if (hb >= 0)
		ionic_link_status_check_request(ionic->lif, CAN_NOT_SLEEP);
	if (hb >= 0 &&
	    !test_bit(IONIC_LIF_F_FW_RESET, lif->state))
		ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
}

void ionic_init_devinfo(struct ionic *ionic)
+10 −6
Original line number Diff line number Diff line
@@ -29,11 +29,9 @@ static void ionic_get_stats_strings(struct ionic_lif *lif, u8 *buf)
static void ionic_get_stats(struct net_device *netdev,
			    struct ethtool_stats *stats, u64 *buf)
{
	struct ionic_lif *lif;
	struct ionic_lif *lif = netdev_priv(netdev);
	u32 i;

	lif = netdev_priv(netdev);

	memset(buf, 0, stats->n_stats * sizeof(*buf));
	for (i = 0; i < ionic_num_stats_grps; i++)
		ionic_stats_groups[i].get_values(lif, &buf);
@@ -209,6 +207,14 @@ static int ionic_get_link_ksettings(struct net_device *netdev,
		ethtool_link_ksettings_add_link_mode(ks, supported,
						     10000baseER_Full);
		break;
	case IONIC_XCVR_PID_SFP_10GBASE_T:
		ethtool_link_ksettings_add_link_mode(ks, supported,
						     10000baseT_Full);
		break;
	case IONIC_XCVR_PID_SFP_1000BASE_T:
		ethtool_link_ksettings_add_link_mode(ks, supported,
						     1000baseT_Full);
		break;
	case IONIC_XCVR_PID_UNKNOWN:
		/* This means there's no module plugged in */
		break;
@@ -264,12 +270,10 @@ static int ionic_set_link_ksettings(struct net_device *netdev,
				    const struct ethtool_link_ksettings *ks)
{
	struct ionic_lif *lif = netdev_priv(netdev);
	struct ionic_dev *idev = &lif->ionic->idev;
	struct ionic *ionic = lif->ionic;
	struct ionic_dev *idev;
	int err = 0;

	idev = &lif->ionic->idev;

	/* set autoneg */
	if (ks->base.autoneg != idev->port_info->config.an_enable) {
		mutex_lock(&ionic->dev_cmd_lock);
+15 −13
Original line number Diff line number Diff line
@@ -320,7 +320,7 @@ struct ionic_lif_identify_comp {
/**
 * enum ionic_lif_capability - LIF capabilities
 * @IONIC_LIF_CAP_ETH:     LIF supports Ethernet
 * @IONIC_LIF_CAP_RDMA:    LIF support RDMA
 * @IONIC_LIF_CAP_RDMA:    LIF supports RDMA
 */
enum ionic_lif_capability {
	IONIC_LIF_CAP_ETH        = BIT(0),
@@ -404,7 +404,7 @@ union ionic_lif_config {
 *     @max_ucast_filters:  Number of perfect unicast addresses supported
 *     @max_mcast_filters:  Number of perfect multicast addresses supported
 *     @min_frame_size:     Minimum size of frames to be sent
 *     @max_frame_size:     Maximim size of frames to be sent
 *     @max_frame_size:     Maximum size of frames to be sent
 *     @config:             LIF config struct with features, mtu, mac, q counts
 *
 * @rdma:                RDMA identify structure
@@ -692,7 +692,7 @@ enum ionic_txq_desc_opcode {
 *                      checksums are also updated.
 *
 *                   IONIC_TXQ_DESC_OPCODE_TSO:
 *                      Device preforms TCP segmentation offload
 *                      Device performs TCP segmentation offload
 *                      (TSO).  @hdr_len is the number of bytes
 *                      to the end of TCP header (the offset to
 *                      the TCP payload).  @mss is the desired
@@ -982,13 +982,13 @@ struct ionic_rxq_comp {
};

enum ionic_pkt_type {
	IONIC_PKT_TYPE_NON_IP     = 0x000,
	IONIC_PKT_TYPE_IPV4       = 0x001,
	IONIC_PKT_TYPE_IPV4_TCP   = 0x003,
	IONIC_PKT_TYPE_IPV4_UDP   = 0x005,
	IONIC_PKT_TYPE_IPV6       = 0x008,
	IONIC_PKT_TYPE_IPV6_TCP   = 0x018,
	IONIC_PKT_TYPE_IPV6_UDP   = 0x028,
	IONIC_PKT_TYPE_NON_IP		= 0x00,
	IONIC_PKT_TYPE_IPV4		= 0x01,
	IONIC_PKT_TYPE_IPV4_TCP		= 0x03,
	IONIC_PKT_TYPE_IPV4_UDP		= 0x05,
	IONIC_PKT_TYPE_IPV6		= 0x08,
	IONIC_PKT_TYPE_IPV6_TCP		= 0x18,
	IONIC_PKT_TYPE_IPV6_UDP		= 0x28,
	/* below types are only used if encap offloads are enabled on lif */
	IONIC_PKT_TYPE_ENCAP_NON_IP	= 0x40,
	IONIC_PKT_TYPE_ENCAP_IPV4	= 0x41,
@@ -1111,6 +1111,8 @@ enum ionic_xcvr_pid {
	IONIC_XCVR_PID_QSFP_100G_CWDM4  = 69,
	IONIC_XCVR_PID_QSFP_100G_PSM4   = 70,
	IONIC_XCVR_PID_SFP_25GBASE_ACC  = 71,
	IONIC_XCVR_PID_SFP_10GBASE_T    = 72,
	IONIC_XCVR_PID_SFP_1000BASE_T   = 73,
};

/**
@@ -1331,7 +1333,7 @@ enum ionic_stats_ctl_cmd {
 * @IONIC_PORT_ATTR_STATE:      Port state attribute
 * @IONIC_PORT_ATTR_SPEED:      Port speed attribute
 * @IONIC_PORT_ATTR_MTU:        Port MTU attribute
 * @IONIC_PORT_ATTR_AUTONEG:    Port autonegotation attribute
 * @IONIC_PORT_ATTR_AUTONEG:    Port autonegotiation attribute
 * @IONIC_PORT_ATTR_FEC:        Port FEC attribute
 * @IONIC_PORT_ATTR_PAUSE:      Port pause attribute
 * @IONIC_PORT_ATTR_LOOPBACK:   Port loopback attribute
@@ -1951,8 +1953,8 @@ enum ionic_qos_sched_type {
 * @pfc_cos:		Priority-Flow Control class of service
 * @dwrr_weight:	QoS class scheduling weight
 * @strict_rlmt:	Rate limit for strict priority scheduling
 * @rw_dot1q_pcp:	Rewrite dot1q pcp to this value	(valid iff F_RW_DOT1Q_PCP)
 * @rw_ip_dscp:		Rewrite ip dscp to this value	(valid iff F_RW_IP_DSCP)
 * @rw_dot1q_pcp:	Rewrite dot1q pcp to value (valid iff F_RW_DOT1Q_PCP)
 * @rw_ip_dscp:		Rewrite ip dscp to value (valid iff F_RW_IP_DSCP)
 * @dot1q_pcp:		Dot1q pcp value
 * @ndscp:		Number of valid dscp values in the ip_dscp field
 * @ip_dscp:		IP dscp values
+54 −23
Original line number Diff line number Diff line
@@ -120,23 +120,34 @@ static void ionic_link_status_check(struct ionic_lif *lif)
	if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state))
		return;

	/* Don't put carrier back up if we're in a broken state */
	if (test_bit(IONIC_LIF_F_BROKEN, lif->state)) {
		clear_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state);
		return;
	}

	link_status = le16_to_cpu(lif->info->status.link_status);
	link_up = link_status == IONIC_PORT_OPER_STATUS_UP;

	if (link_up) {
		if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) {
		int err = 0;

		if (netdev->flags & IFF_UP && netif_running(netdev)) {
			mutex_lock(&lif->queue_lock);
			ionic_start_queues(lif);
			err = ionic_start_queues(lif);
			if (err) {
				netdev_err(lif->netdev,
					   "Failed to start queues: %d\n", err);
				set_bit(IONIC_LIF_F_BROKEN, lif->state);
				netif_carrier_off(lif->netdev);
			}
			mutex_unlock(&lif->queue_lock);
		}

		if (!netif_carrier_ok(netdev)) {
			u32 link_speed;

		if (!err && !netif_carrier_ok(netdev)) {
			ionic_port_identify(lif->ionic);
			link_speed = le32_to_cpu(lif->info->status.link_speed);
			netdev_info(netdev, "Link up - %d Gbps\n",
				    link_speed / 1000);
				    le32_to_cpu(lif->info->status.link_speed) / 1000);
			netif_carrier_on(netdev);
		}
	} else {
@@ -145,7 +156,7 @@ static void ionic_link_status_check(struct ionic_lif *lif)
			netif_carrier_off(netdev);
		}

		if (lif->netdev->flags & IFF_UP && netif_running(lif->netdev)) {
		if (netdev->flags & IFF_UP && netif_running(netdev)) {
			mutex_lock(&lif->queue_lock);
			ionic_stop_queues(lif);
			mutex_unlock(&lif->queue_lock);
@@ -382,6 +393,8 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq)
static void ionic_qcqs_free(struct ionic_lif *lif)
{
	struct device *dev = lif->ionic->dev;
	struct ionic_qcq *adminqcq;
	unsigned long irqflags;

	if (lif->notifyqcq) {
		ionic_qcq_free(lif, lif->notifyqcq);
@@ -390,9 +403,14 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
	}

	if (lif->adminqcq) {
		ionic_qcq_free(lif, lif->adminqcq);
		devm_kfree(dev, lif->adminqcq);
		spin_lock_irqsave(&lif->adminq_lock, irqflags);
		adminqcq = READ_ONCE(lif->adminqcq);
		lif->adminqcq = NULL;
		spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
		if (adminqcq) {
			ionic_qcq_free(lif, adminqcq);
			devm_kfree(dev, adminqcq);
		}
	}

	if (lif->rxqcqs) {
@@ -718,10 +736,8 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
	unsigned int intr_index;
	int err;

	if (qcq->flags & IONIC_QCQ_F_INTR)
	intr_index = qcq->intr.index;
	else
		intr_index = lif->rxqcqs[q->index]->intr.index;

	ctx.cmd.q_init.intr_index = cpu_to_le16(intr_index);

	dev_dbg(dev, "txq_init.pid %d\n", ctx.cmd.q_init.pid);
@@ -839,7 +855,7 @@ static bool ionic_notifyq_service(struct ionic_cq *cq,

	switch (le16_to_cpu(comp->event.ecode)) {
	case IONIC_EVENT_LINK_CHANGE:
		ionic_link_status_check_request(lif, false);
		ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
		break;
	case IONIC_EVENT_RESET:
		work = kzalloc(sizeof(*work), GFP_ATOMIC);
@@ -877,6 +893,7 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
	struct ionic_intr_info *intr = napi_to_cq(napi)->bound_intr;
	struct ionic_lif *lif = napi_to_cq(napi)->lif;
	struct ionic_dev *idev = &lif->ionic->idev;
	unsigned long irqflags;
	unsigned int flags = 0;
	int n_work = 0;
	int a_work = 0;
@@ -886,14 +903,16 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
		n_work = ionic_cq_service(&lif->notifyqcq->cq, budget,
					  ionic_notifyq_service, NULL, NULL);

	spin_lock_irqsave(&lif->adminq_lock, irqflags);
	if (lif->adminqcq && lif->adminqcq->flags & IONIC_QCQ_F_INITED)
		a_work = ionic_cq_service(&lif->adminqcq->cq, budget,
					  ionic_adminq_service, NULL, NULL);
	spin_unlock_irqrestore(&lif->adminq_lock, irqflags);

	work_done = max(n_work, a_work);
	if (work_done < budget && napi_complete_done(napi, work_done)) {
		flags |= IONIC_INTR_CRED_UNMASK;
		lif->adminqcq->cq.bound_intr->rearm_count++;
		intr->rearm_count++;
	}

	if (work_done || flags) {
@@ -1443,7 +1462,7 @@ static int ionic_start_queues_reconfig(struct ionic_lif *lif)
	 */
	err = ionic_txrx_init(lif);
	mutex_unlock(&lif->queue_lock);
	ionic_link_status_check_request(lif, true);
	ionic_link_status_check_request(lif, CAN_SLEEP);
	netif_device_attach(lif->netdev);

	return err;
@@ -1482,7 +1501,8 @@ static void ionic_tx_timeout_work(struct work_struct *ws)
{
	struct ionic_lif *lif = container_of(ws, struct ionic_lif, tx_timeout_work);

	netdev_info(lif->netdev, "Tx Timeout recovery\n");
	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
		return;

	/* if we were stopped before this scheduled job was launched,
	 * don't bother the queues as they are already stopped.
@@ -1498,6 +1518,7 @@ static void ionic_tx_timeout(struct net_device *netdev, unsigned int txqueue)
{
	struct ionic_lif *lif = netdev_priv(netdev);

	netdev_info(lif->netdev, "Tx Timeout triggered - txq %d\n", txqueue);
	schedule_work(&lif->tx_timeout_work);
}

@@ -1839,6 +1860,12 @@ static int ionic_start_queues(struct ionic_lif *lif)
{
	int err;

	if (test_bit(IONIC_LIF_F_BROKEN, lif->state))
		return -EIO;

	if (test_bit(IONIC_LIF_F_FW_RESET, lif->state))
		return -EBUSY;

	if (test_and_set_bit(IONIC_LIF_F_UP, lif->state))
		return 0;

@@ -1857,13 +1884,17 @@ static int ionic_open(struct net_device *netdev)
	struct ionic_lif *lif = netdev_priv(netdev);
	int err;

	/* If recovering from a broken state, clear the bit and we'll try again */
	if (test_and_clear_bit(IONIC_LIF_F_BROKEN, lif->state))
		netdev_info(netdev, "clearing broken state\n");

	err = ionic_txrx_alloc(lif);
	if (err)
		return err;

	err = ionic_txrx_init(lif);
	if (err)
		goto err_out;
		goto err_txrx_free;

	err = netif_set_real_num_tx_queues(netdev, lif->nxqs);
	if (err)
@@ -1884,7 +1915,7 @@ static int ionic_open(struct net_device *netdev)

err_txrx_deinit:
	ionic_txrx_deinit(lif);
err_out:
err_txrx_free:
	ionic_txrx_free(lif);
	return err;
}
@@ -2356,7 +2387,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
	swap(lif->nxqs, qparam->nxqs);

err_out_reinit_unlock:
	/* re-init the queues, but don't loose an error code */
	/* re-init the queues, but don't lose an error code */
	if (err)
		ionic_start_queues_reconfig(lif);
	else
@@ -2605,7 +2636,7 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
	}

	clear_bit(IONIC_LIF_F_FW_RESET, lif->state);
	ionic_link_status_check_request(lif, true);
	ionic_link_status_check_request(lif, CAN_SLEEP);
	netif_device_attach(lif->netdev);
	dev_info(ionic->dev, "FW Up: LIFs restarted\n");

@@ -2976,7 +3007,7 @@ int ionic_lif_register(struct ionic_lif *lif)
		return err;
	}

	ionic_link_status_check_request(lif, true);
	ionic_link_status_check_request(lif, CAN_SLEEP);
	lif->registered = true;
	ionic_lif_set_netdev_info(lif);

Loading