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

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
...@@ -184,6 +184,10 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int num_vfs) ...@@ -184,6 +184,10 @@ static int ionic_sriov_configure(struct pci_dev *pdev, int num_vfs)
struct device *dev = ionic->dev; struct device *dev = ionic->dev;
int ret = 0; int ret = 0;
if (ionic->lif &&
test_bit(IONIC_LIF_F_FW_RESET, ionic->lif->state))
return -EBUSY;
if (num_vfs > 0) { if (num_vfs > 0) {
ret = pci_enable_sriov(pdev, num_vfs); ret = pci_enable_sriov(pdev, num_vfs);
if (ret) { if (ret) {
......
...@@ -14,18 +14,20 @@ ...@@ -14,18 +14,20 @@
static void ionic_watchdog_cb(struct timer_list *t) static void ionic_watchdog_cb(struct timer_list *t)
{ {
struct ionic *ionic = from_timer(ionic, t, watchdog_timer); struct ionic *ionic = from_timer(ionic, t, watchdog_timer);
struct ionic_lif *lif = ionic->lif;
int hb; int hb;
mod_timer(&ionic->watchdog_timer, mod_timer(&ionic->watchdog_timer,
round_jiffies(jiffies + ionic->watchdog_period)); round_jiffies(jiffies + ionic->watchdog_period));
if (!ionic->lif) if (!lif)
return; return;
hb = ionic_heartbeat_check(ionic); hb = ionic_heartbeat_check(ionic);
if (hb >= 0) if (hb >= 0 &&
ionic_link_status_check_request(ionic->lif, CAN_NOT_SLEEP); !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) void ionic_init_devinfo(struct ionic *ionic)
......
...@@ -29,11 +29,9 @@ static void ionic_get_stats_strings(struct ionic_lif *lif, u8 *buf) ...@@ -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, static void ionic_get_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *buf) struct ethtool_stats *stats, u64 *buf)
{ {
struct ionic_lif *lif; struct ionic_lif *lif = netdev_priv(netdev);
u32 i; u32 i;
lif = netdev_priv(netdev);
memset(buf, 0, stats->n_stats * sizeof(*buf)); memset(buf, 0, stats->n_stats * sizeof(*buf));
for (i = 0; i < ionic_num_stats_grps; i++) for (i = 0; i < ionic_num_stats_grps; i++)
ionic_stats_groups[i].get_values(lif, &buf); ionic_stats_groups[i].get_values(lif, &buf);
...@@ -209,6 +207,14 @@ static int ionic_get_link_ksettings(struct net_device *netdev, ...@@ -209,6 +207,14 @@ static int ionic_get_link_ksettings(struct net_device *netdev,
ethtool_link_ksettings_add_link_mode(ks, supported, ethtool_link_ksettings_add_link_mode(ks, supported,
10000baseER_Full); 10000baseER_Full);
break; 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: case IONIC_XCVR_PID_UNKNOWN:
/* This means there's no module plugged in */ /* This means there's no module plugged in */
break; break;
...@@ -264,12 +270,10 @@ static int ionic_set_link_ksettings(struct net_device *netdev, ...@@ -264,12 +270,10 @@ static int ionic_set_link_ksettings(struct net_device *netdev,
const struct ethtool_link_ksettings *ks) const struct ethtool_link_ksettings *ks)
{ {
struct ionic_lif *lif = netdev_priv(netdev); struct ionic_lif *lif = netdev_priv(netdev);
struct ionic_dev *idev = &lif->ionic->idev;
struct ionic *ionic = lif->ionic; struct ionic *ionic = lif->ionic;
struct ionic_dev *idev;
int err = 0; int err = 0;
idev = &lif->ionic->idev;
/* set autoneg */ /* set autoneg */
if (ks->base.autoneg != idev->port_info->config.an_enable) { if (ks->base.autoneg != idev->port_info->config.an_enable) {
mutex_lock(&ionic->dev_cmd_lock); mutex_lock(&ionic->dev_cmd_lock);
......
...@@ -320,7 +320,7 @@ struct ionic_lif_identify_comp { ...@@ -320,7 +320,7 @@ struct ionic_lif_identify_comp {
/** /**
* enum ionic_lif_capability - LIF capabilities * enum ionic_lif_capability - LIF capabilities
* @IONIC_LIF_CAP_ETH: LIF supports Ethernet * @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 { enum ionic_lif_capability {
IONIC_LIF_CAP_ETH = BIT(0), IONIC_LIF_CAP_ETH = BIT(0),
...@@ -404,7 +404,7 @@ union ionic_lif_config { ...@@ -404,7 +404,7 @@ union ionic_lif_config {
* @max_ucast_filters: Number of perfect unicast addresses supported * @max_ucast_filters: Number of perfect unicast addresses supported
* @max_mcast_filters: Number of perfect multicast addresses supported * @max_mcast_filters: Number of perfect multicast addresses supported
* @min_frame_size: Minimum size of frames to be sent * @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 * @config: LIF config struct with features, mtu, mac, q counts
* *
* @rdma: RDMA identify structure * @rdma: RDMA identify structure
...@@ -692,7 +692,7 @@ enum ionic_txq_desc_opcode { ...@@ -692,7 +692,7 @@ enum ionic_txq_desc_opcode {
* checksums are also updated. * checksums are also updated.
* *
* IONIC_TXQ_DESC_OPCODE_TSO: * IONIC_TXQ_DESC_OPCODE_TSO:
* Device preforms TCP segmentation offload * Device performs TCP segmentation offload
* (TSO). @hdr_len is the number of bytes * (TSO). @hdr_len is the number of bytes
* to the end of TCP header (the offset to * to the end of TCP header (the offset to
* the TCP payload). @mss is the desired * the TCP payload). @mss is the desired
...@@ -982,13 +982,13 @@ struct ionic_rxq_comp { ...@@ -982,13 +982,13 @@ struct ionic_rxq_comp {
}; };
enum ionic_pkt_type { enum ionic_pkt_type {
IONIC_PKT_TYPE_NON_IP = 0x000, IONIC_PKT_TYPE_NON_IP = 0x00,
IONIC_PKT_TYPE_IPV4 = 0x001, IONIC_PKT_TYPE_IPV4 = 0x01,
IONIC_PKT_TYPE_IPV4_TCP = 0x003, IONIC_PKT_TYPE_IPV4_TCP = 0x03,
IONIC_PKT_TYPE_IPV4_UDP = 0x005, IONIC_PKT_TYPE_IPV4_UDP = 0x05,
IONIC_PKT_TYPE_IPV6 = 0x008, IONIC_PKT_TYPE_IPV6 = 0x08,
IONIC_PKT_TYPE_IPV6_TCP = 0x018, IONIC_PKT_TYPE_IPV6_TCP = 0x18,
IONIC_PKT_TYPE_IPV6_UDP = 0x028, IONIC_PKT_TYPE_IPV6_UDP = 0x28,
/* below types are only used if encap offloads are enabled on lif */ /* below types are only used if encap offloads are enabled on lif */
IONIC_PKT_TYPE_ENCAP_NON_IP = 0x40, IONIC_PKT_TYPE_ENCAP_NON_IP = 0x40,
IONIC_PKT_TYPE_ENCAP_IPV4 = 0x41, IONIC_PKT_TYPE_ENCAP_IPV4 = 0x41,
...@@ -1111,6 +1111,8 @@ enum ionic_xcvr_pid { ...@@ -1111,6 +1111,8 @@ enum ionic_xcvr_pid {
IONIC_XCVR_PID_QSFP_100G_CWDM4 = 69, IONIC_XCVR_PID_QSFP_100G_CWDM4 = 69,
IONIC_XCVR_PID_QSFP_100G_PSM4 = 70, IONIC_XCVR_PID_QSFP_100G_PSM4 = 70,
IONIC_XCVR_PID_SFP_25GBASE_ACC = 71, 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 { ...@@ -1331,7 +1333,7 @@ enum ionic_stats_ctl_cmd {
* @IONIC_PORT_ATTR_STATE: Port state attribute * @IONIC_PORT_ATTR_STATE: Port state attribute
* @IONIC_PORT_ATTR_SPEED: Port speed attribute * @IONIC_PORT_ATTR_SPEED: Port speed attribute
* @IONIC_PORT_ATTR_MTU: Port MTU 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_FEC: Port FEC attribute
* @IONIC_PORT_ATTR_PAUSE: Port pause attribute * @IONIC_PORT_ATTR_PAUSE: Port pause attribute
* @IONIC_PORT_ATTR_LOOPBACK: Port loopback attribute * @IONIC_PORT_ATTR_LOOPBACK: Port loopback attribute
...@@ -1951,8 +1953,8 @@ enum ionic_qos_sched_type { ...@@ -1951,8 +1953,8 @@ enum ionic_qos_sched_type {
* @pfc_cos: Priority-Flow Control class of service * @pfc_cos: Priority-Flow Control class of service
* @dwrr_weight: QoS class scheduling weight * @dwrr_weight: QoS class scheduling weight
* @strict_rlmt: Rate limit for strict priority scheduling * @strict_rlmt: Rate limit for strict priority scheduling
* @rw_dot1q_pcp: Rewrite dot1q pcp to this value (valid iff F_RW_DOT1Q_PCP) * @rw_dot1q_pcp: Rewrite dot1q pcp to value (valid iff F_RW_DOT1Q_PCP)
* @rw_ip_dscp: Rewrite ip dscp to this value (valid iff F_RW_IP_DSCP) * @rw_ip_dscp: Rewrite ip dscp to value (valid iff F_RW_IP_DSCP)
* @dot1q_pcp: Dot1q pcp value * @dot1q_pcp: Dot1q pcp value
* @ndscp: Number of valid dscp values in the ip_dscp field * @ndscp: Number of valid dscp values in the ip_dscp field
* @ip_dscp: IP dscp values * @ip_dscp: IP dscp values
......
...@@ -120,23 +120,34 @@ static void ionic_link_status_check(struct ionic_lif *lif) ...@@ -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)) if (!test_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state))
return; 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_status = le16_to_cpu(lif->info->status.link_status);
link_up = link_status == IONIC_PORT_OPER_STATUS_UP; link_up = link_status == IONIC_PORT_OPER_STATUS_UP;
if (link_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); 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); mutex_unlock(&lif->queue_lock);
} }
if (!netif_carrier_ok(netdev)) { if (!err && !netif_carrier_ok(netdev)) {
u32 link_speed;
ionic_port_identify(lif->ionic); ionic_port_identify(lif->ionic);
link_speed = le32_to_cpu(lif->info->status.link_speed);
netdev_info(netdev, "Link up - %d Gbps\n", netdev_info(netdev, "Link up - %d Gbps\n",
link_speed / 1000); le32_to_cpu(lif->info->status.link_speed) / 1000);
netif_carrier_on(netdev); netif_carrier_on(netdev);
} }
} else { } else {
...@@ -145,7 +156,7 @@ static void ionic_link_status_check(struct ionic_lif *lif) ...@@ -145,7 +156,7 @@ static void ionic_link_status_check(struct ionic_lif *lif)
netif_carrier_off(netdev); 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); mutex_lock(&lif->queue_lock);
ionic_stop_queues(lif); ionic_stop_queues(lif);
mutex_unlock(&lif->queue_lock); mutex_unlock(&lif->queue_lock);
...@@ -382,6 +393,8 @@ static void ionic_qcq_free(struct ionic_lif *lif, struct ionic_qcq *qcq) ...@@ -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) static void ionic_qcqs_free(struct ionic_lif *lif)
{ {
struct device *dev = lif->ionic->dev; struct device *dev = lif->ionic->dev;
struct ionic_qcq *adminqcq;
unsigned long irqflags;
if (lif->notifyqcq) { if (lif->notifyqcq) {
ionic_qcq_free(lif, lif->notifyqcq); ionic_qcq_free(lif, lif->notifyqcq);
...@@ -390,9 +403,14 @@ static void ionic_qcqs_free(struct ionic_lif *lif) ...@@ -390,9 +403,14 @@ static void ionic_qcqs_free(struct ionic_lif *lif)
} }
if (lif->adminqcq) { if (lif->adminqcq) {
ionic_qcq_free(lif, lif->adminqcq); spin_lock_irqsave(&lif->adminq_lock, irqflags);
devm_kfree(dev, lif->adminqcq); adminqcq = READ_ONCE(lif->adminqcq);
lif->adminqcq = NULL; lif->adminqcq = NULL;
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
if (adminqcq) {
ionic_qcq_free(lif, adminqcq);
devm_kfree(dev, adminqcq);
}
} }
if (lif->rxqcqs) { if (lif->rxqcqs) {
...@@ -718,10 +736,8 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq) ...@@ -718,10 +736,8 @@ static int ionic_lif_txq_init(struct ionic_lif *lif, struct ionic_qcq *qcq)
unsigned int intr_index; unsigned int intr_index;
int err; int err;
if (qcq->flags & IONIC_QCQ_F_INTR) intr_index = qcq->intr.index;
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); ctx.cmd.q_init.intr_index = cpu_to_le16(intr_index);
dev_dbg(dev, "txq_init.pid %d\n", ctx.cmd.q_init.pid); 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, ...@@ -839,7 +855,7 @@ static bool ionic_notifyq_service(struct ionic_cq *cq,
switch (le16_to_cpu(comp->event.ecode)) { switch (le16_to_cpu(comp->event.ecode)) {
case IONIC_EVENT_LINK_CHANGE: case IONIC_EVENT_LINK_CHANGE:
ionic_link_status_check_request(lif, false); ionic_link_status_check_request(lif, CAN_NOT_SLEEP);
break; break;
case IONIC_EVENT_RESET: case IONIC_EVENT_RESET:
work = kzalloc(sizeof(*work), GFP_ATOMIC); work = kzalloc(sizeof(*work), GFP_ATOMIC);
...@@ -877,6 +893,7 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget) ...@@ -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_intr_info *intr = napi_to_cq(napi)->bound_intr;
struct ionic_lif *lif = napi_to_cq(napi)->lif; struct ionic_lif *lif = napi_to_cq(napi)->lif;
struct ionic_dev *idev = &lif->ionic->idev; struct ionic_dev *idev = &lif->ionic->idev;
unsigned long irqflags;
unsigned int flags = 0; unsigned int flags = 0;
int n_work = 0; int n_work = 0;
int a_work = 0; int a_work = 0;
...@@ -886,14 +903,16 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget) ...@@ -886,14 +903,16 @@ static int ionic_adminq_napi(struct napi_struct *napi, int budget)
n_work = ionic_cq_service(&lif->notifyqcq->cq, budget, n_work = ionic_cq_service(&lif->notifyqcq->cq, budget,
ionic_notifyq_service, NULL, NULL); ionic_notifyq_service, NULL, NULL);
spin_lock_irqsave(&lif->adminq_lock, irqflags);
if (lif->adminqcq && lif->adminqcq->flags & IONIC_QCQ_F_INITED) if (lif->adminqcq && lif->adminqcq->flags & IONIC_QCQ_F_INITED)
a_work = ionic_cq_service(&lif->adminqcq->cq, budget, a_work = ionic_cq_service(&lif->adminqcq->cq, budget,
ionic_adminq_service, NULL, NULL); ionic_adminq_service, NULL, NULL);
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
work_done = max(n_work, a_work); work_done = max(n_work, a_work);
if (work_done < budget && napi_complete_done(napi, work_done)) { if (work_done < budget && napi_complete_done(napi, work_done)) {
flags |= IONIC_INTR_CRED_UNMASK; flags |= IONIC_INTR_CRED_UNMASK;
lif->adminqcq->cq.bound_intr->rearm_count++; intr->rearm_count++;
} }
if (work_done || flags) { if (work_done || flags) {
...@@ -1443,7 +1462,7 @@ static int ionic_start_queues_reconfig(struct ionic_lif *lif) ...@@ -1443,7 +1462,7 @@ static int ionic_start_queues_reconfig(struct ionic_lif *lif)
*/ */
err = ionic_txrx_init(lif); err = ionic_txrx_init(lif);
mutex_unlock(&lif->queue_lock); 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); netif_device_attach(lif->netdev);
return err; return err;
...@@ -1482,7 +1501,8 @@ static void ionic_tx_timeout_work(struct work_struct *ws) ...@@ -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); 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, /* if we were stopped before this scheduled job was launched,
* don't bother the queues as they are already stopped. * 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) ...@@ -1498,6 +1518,7 @@ static void ionic_tx_timeout(struct net_device *netdev, unsigned int txqueue)
{ {
struct ionic_lif *lif = netdev_priv(netdev); struct ionic_lif *lif = netdev_priv(netdev);
netdev_info(lif->netdev, "Tx Timeout triggered - txq %d\n", txqueue);
schedule_work(&lif->tx_timeout_work); schedule_work(&lif->tx_timeout_work);
} }
...@@ -1839,6 +1860,12 @@ static int ionic_start_queues(struct ionic_lif *lif) ...@@ -1839,6 +1860,12 @@ static int ionic_start_queues(struct ionic_lif *lif)
{ {
int err; 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)) if (test_and_set_bit(IONIC_LIF_F_UP, lif->state))
return 0; return 0;
...@@ -1857,13 +1884,17 @@ static int ionic_open(struct net_device *netdev) ...@@ -1857,13 +1884,17 @@ static int ionic_open(struct net_device *netdev)
struct ionic_lif *lif = netdev_priv(netdev); struct ionic_lif *lif = netdev_priv(netdev);
int err; 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); err = ionic_txrx_alloc(lif);
if (err) if (err)
return err; return err;
err = ionic_txrx_init(lif); err = ionic_txrx_init(lif);
if (err) if (err)
goto err_out; goto err_txrx_free;
err = netif_set_real_num_tx_queues(netdev, lif->nxqs); err = netif_set_real_num_tx_queues(netdev, lif->nxqs);
if (err) if (err)
...@@ -1884,7 +1915,7 @@ static int ionic_open(struct net_device *netdev) ...@@ -1884,7 +1915,7 @@ static int ionic_open(struct net_device *netdev)
err_txrx_deinit: err_txrx_deinit:
ionic_txrx_deinit(lif); ionic_txrx_deinit(lif);
err_out: err_txrx_free:
ionic_txrx_free(lif); ionic_txrx_free(lif);
return err; return err;
} }
...@@ -2356,7 +2387,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif, ...@@ -2356,7 +2387,7 @@ int ionic_reconfigure_queues(struct ionic_lif *lif,
swap(lif->nxqs, qparam->nxqs); swap(lif->nxqs, qparam->nxqs);
err_out_reinit_unlock: 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) if (err)
ionic_start_queues_reconfig(lif); ionic_start_queues_reconfig(lif);
else else
...@@ -2605,7 +2636,7 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif) ...@@ -2605,7 +2636,7 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
} }
clear_bit(IONIC_LIF_F_FW_RESET, lif->state); 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); netif_device_attach(lif->netdev);
dev_info(ionic->dev, "FW Up: LIFs restarted\n"); dev_info(ionic->dev, "FW Up: LIFs restarted\n");
...@@ -2976,7 +3007,7 @@ int ionic_lif_register(struct ionic_lif *lif) ...@@ -2976,7 +3007,7 @@ int ionic_lif_register(struct ionic_lif *lif)
return err; return err;
} }
ionic_link_status_check_request(lif, true); ionic_link_status_check_request(lif, CAN_SLEEP);
lif->registered = true; lif->registered = true;
ionic_lif_set_netdev_info(lif); ionic_lif_set_netdev_info(lif);
......
...@@ -139,6 +139,7 @@ enum ionic_lif_state_flags { ...@@ -139,6 +139,7 @@ enum ionic_lif_state_flags {
IONIC_LIF_F_LINK_CHECK_REQUESTED, IONIC_LIF_F_LINK_CHECK_REQUESTED,
IONIC_LIF_F_FW_RESET, IONIC_LIF_F_FW_RESET,
IONIC_LIF_F_SPLIT_INTR, IONIC_LIF_F_SPLIT_INTR,
IONIC_LIF_F_BROKEN,
IONIC_LIF_F_TX_DIM_INTR, IONIC_LIF_F_TX_DIM_INTR,
IONIC_LIF_F_RX_DIM_INTR, IONIC_LIF_F_RX_DIM_INTR,
......
...@@ -187,10 +187,17 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode) ...@@ -187,10 +187,17 @@ static const char *ionic_opcode_to_str(enum ionic_cmd_opcode opcode)
static void ionic_adminq_flush(struct ionic_lif *lif) static void ionic_adminq_flush(struct ionic_lif *lif)
{ {
struct ionic_queue *q = &lif->adminqcq->q;
struct ionic_desc_info *desc_info; struct ionic_desc_info *desc_info;
unsigned long irqflags;
struct ionic_queue *q;
spin_lock_irqsave(&lif->adminq_lock, irqflags);
if (!lif->adminqcq) {
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
return;
}
spin_lock(&lif->adminq_lock); q = &lif->adminqcq->q;
while (q->tail_idx != q->head_idx) { while (q->tail_idx != q->head_idx) {
desc_info = &q->info[q->tail_idx]; desc_info = &q->info[q->tail_idx];
...@@ -199,7 +206,7 @@ static void ionic_adminq_flush(struct ionic_lif *lif) ...@@ -199,7 +206,7 @@ static void ionic_adminq_flush(struct ionic_lif *lif)
desc_info->cb_arg = NULL; desc_info->cb_arg = NULL;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1); q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
} }
spin_unlock(&lif->adminq_lock); spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
} }
static int ionic_adminq_check_err(struct ionic_lif *lif, static int ionic_adminq_check_err(struct ionic_lif *lif,
...@@ -252,15 +259,18 @@ static void ionic_adminq_cb(struct ionic_queue *q, ...@@ -252,15 +259,18 @@ static void ionic_adminq_cb(struct ionic_queue *q,
static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{ {
struct ionic_desc_info *desc_info; struct ionic_desc_info *desc_info;
unsigned long irqflags;
struct ionic_queue *q; struct ionic_queue *q;
int err = 0; int err = 0;
if (!lif->adminqcq) spin_lock_irqsave(&lif->adminq_lock, irqflags);
if (!lif->adminqcq) {
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
return -EIO; return -EIO;
}
q = &lif->adminqcq->q; q = &lif->adminqcq->q;
spin_lock(&lif->adminq_lock);
if (!ionic_q_has_space(q, 1)) { if (!ionic_q_has_space(q, 1)) {
err = -ENOSPC; err = -ENOSPC;
goto err_out; goto err_out;
...@@ -280,7 +290,7 @@ static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx) ...@@ -280,7 +290,7 @@ static int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
ionic_q_post(q, true, ionic_adminq_cb, ctx); ionic_q_post(q, true, ionic_adminq_cb, ctx);
err_out: err_out:
spin_unlock(&lif->adminq_lock); spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment