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. ====================
This commit is contained in:
commit
84b9000a4b
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
intr_index = qcq->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);
|
||||
|
||||
|
@ -139,6 +139,7 @@ enum ionic_lif_state_flags {
|
||||
IONIC_LIF_F_LINK_CHECK_REQUESTED,
|
||||
IONIC_LIF_F_FW_RESET,
|
||||
IONIC_LIF_F_SPLIT_INTR,
|
||||
IONIC_LIF_F_BROKEN,
|
||||
IONIC_LIF_F_TX_DIM_INTR,
|
||||
IONIC_LIF_F_RX_DIM_INTR,
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
struct ionic_queue *q = &lif->adminqcq->q;
|
||||
struct ionic_desc_info *desc_info;
|
||||
unsigned long irqflags;
|
||||
struct ionic_queue *q;
|
||||
|
||||
spin_lock(&lif->adminq_lock);
|
||||
spin_lock_irqsave(&lif->adminq_lock, irqflags);
|
||||
if (!lif->adminqcq) {
|
||||
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
|
||||
return;
|
||||
}
|
||||
|
||||
q = &lif->adminqcq->q;
|
||||
|
||||
while (q->tail_idx != q->head_idx) {
|
||||
desc_info = &q->info[q->tail_idx];
|
||||
@ -199,7 +206,7 @@ static void ionic_adminq_flush(struct ionic_lif *lif)
|
||||
desc_info->cb_arg = NULL;
|
||||
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,
|
||||
@ -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)
|
||||
{
|
||||
struct ionic_desc_info *desc_info;
|
||||
unsigned long irqflags;
|
||||
struct ionic_queue *q;
|
||||
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;
|
||||
}
|
||||
|
||||
q = &lif->adminqcq->q;
|
||||
|
||||
spin_lock(&lif->adminq_lock);
|
||||
if (!ionic_q_has_space(q, 1)) {
|
||||
err = -ENOSPC;
|
||||
goto err_out;
|
||||
@ -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);
|
||||
|
||||
err_out:
|
||||
spin_unlock(&lif->adminq_lock);
|
||||
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user