mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 17:41:50 +00:00
Merge branch 'ionic-error-recovery'
Shannon Nelson says: ==================== ionic error recovery This set of patches comes mostly from error recovery path testing, as well as a couple of upstream review comments. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
34ad937770
4 changed files with 134 additions and 88 deletions
|
@ -266,6 +266,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
dev_err(dev, "Cannot identify device: %d, aborting\n", err);
|
dev_err(dev, "Cannot identify device: %d, aborting\n", err);
|
||||||
goto err_out_teardown;
|
goto err_out_teardown;
|
||||||
}
|
}
|
||||||
|
ionic_debugfs_add_ident(ionic);
|
||||||
|
|
||||||
err = ionic_init(ionic);
|
err = ionic_init(ionic);
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -286,14 +287,7 @@ static int ionic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||||
goto err_out_reset;
|
goto err_out_reset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Configure LIFs */
|
/* Allocate and init the LIF */
|
||||||
err = ionic_lif_identify(ionic, IONIC_LIF_TYPE_CLASSIC,
|
|
||||||
&ionic->ident.lif);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "Cannot identify LIFs: %d, aborting\n", err);
|
|
||||||
goto err_out_port_reset;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = ionic_lif_size(ionic);
|
err = ionic_lif_size(ionic);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(dev, "Cannot size LIF: %d, aborting\n", err);
|
dev_err(dev, "Cannot size LIF: %d, aborting\n", err);
|
||||||
|
|
|
@ -96,6 +96,7 @@ enum ionic_status_code {
|
||||||
IONIC_RC_ERROR = 29, /* Generic error */
|
IONIC_RC_ERROR = 29, /* Generic error */
|
||||||
IONIC_RC_ERDMA = 30, /* Generic RDMA error */
|
IONIC_RC_ERDMA = 30, /* Generic RDMA error */
|
||||||
IONIC_RC_EVFID = 31, /* VF ID does not exist */
|
IONIC_RC_EVFID = 31, /* VF ID does not exist */
|
||||||
|
IONIC_RC_EBAD_FW = 32, /* FW file is invalid or corrupted */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ionic_notifyq_opcode {
|
enum ionic_notifyq_opcode {
|
||||||
|
|
|
@ -62,15 +62,18 @@ static void ionic_lif_deferred_work(struct work_struct *work)
|
||||||
struct ionic_deferred *def = &lif->deferred;
|
struct ionic_deferred *def = &lif->deferred;
|
||||||
struct ionic_deferred_work *w = NULL;
|
struct ionic_deferred_work *w = NULL;
|
||||||
|
|
||||||
spin_lock_bh(&def->lock);
|
do {
|
||||||
if (!list_empty(&def->list)) {
|
spin_lock_bh(&def->lock);
|
||||||
w = list_first_entry(&def->list,
|
if (!list_empty(&def->list)) {
|
||||||
struct ionic_deferred_work, list);
|
w = list_first_entry(&def->list,
|
||||||
list_del(&w->list);
|
struct ionic_deferred_work, list);
|
||||||
}
|
list_del(&w->list);
|
||||||
spin_unlock_bh(&def->lock);
|
}
|
||||||
|
spin_unlock_bh(&def->lock);
|
||||||
|
|
||||||
|
if (!w)
|
||||||
|
break;
|
||||||
|
|
||||||
if (w) {
|
|
||||||
switch (w->type) {
|
switch (w->type) {
|
||||||
case IONIC_DW_TYPE_RX_MODE:
|
case IONIC_DW_TYPE_RX_MODE:
|
||||||
ionic_lif_rx_mode(lif, w->rx_mode);
|
ionic_lif_rx_mode(lif, w->rx_mode);
|
||||||
|
@ -94,8 +97,8 @@ static void ionic_lif_deferred_work(struct work_struct *work)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
kfree(w);
|
kfree(w);
|
||||||
schedule_work(&def->work);
|
w = NULL;
|
||||||
}
|
} while (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ionic_lif_deferred_enqueue(struct ionic_deferred *def,
|
void ionic_lif_deferred_enqueue(struct ionic_deferred *def,
|
||||||
|
@ -161,8 +164,10 @@ void ionic_link_status_check_request(struct ionic_lif *lif, bool can_sleep)
|
||||||
|
|
||||||
if (!can_sleep) {
|
if (!can_sleep) {
|
||||||
work = kzalloc(sizeof(*work), GFP_ATOMIC);
|
work = kzalloc(sizeof(*work), GFP_ATOMIC);
|
||||||
if (!work)
|
if (!work) {
|
||||||
|
clear_bit(IONIC_LIF_F_LINK_CHECK_REQUESTED, lif->state);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
work->type = IONIC_DW_TYPE_LINK_STATUS;
|
work->type = IONIC_DW_TYPE_LINK_STATUS;
|
||||||
ionic_lif_deferred_enqueue(&lif->deferred, work);
|
ionic_lif_deferred_enqueue(&lif->deferred, work);
|
||||||
|
@ -259,31 +264,29 @@ static int ionic_qcq_enable(struct ionic_qcq *qcq)
|
||||||
return ionic_adminq_post_wait(lif, &ctx);
|
return ionic_adminq_post_wait(lif, &ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ionic_qcq_disable(struct ionic_qcq *qcq)
|
static int ionic_qcq_disable(struct ionic_qcq *qcq, bool send_to_hw)
|
||||||
{
|
{
|
||||||
struct ionic_queue *q = &qcq->q;
|
struct ionic_queue *q;
|
||||||
struct ionic_lif *lif = q->lif;
|
struct ionic_lif *lif;
|
||||||
struct ionic_dev *idev;
|
int err = 0;
|
||||||
struct device *dev;
|
|
||||||
|
|
||||||
struct ionic_admin_ctx ctx = {
|
struct ionic_admin_ctx ctx = {
|
||||||
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
|
.work = COMPLETION_INITIALIZER_ONSTACK(ctx.work),
|
||||||
.cmd.q_control = {
|
.cmd.q_control = {
|
||||||
.opcode = IONIC_CMD_Q_CONTROL,
|
.opcode = IONIC_CMD_Q_CONTROL,
|
||||||
.lif_index = cpu_to_le16(lif->index),
|
|
||||||
.type = q->type,
|
|
||||||
.index = cpu_to_le32(q->index),
|
|
||||||
.oper = IONIC_Q_DISABLE,
|
.oper = IONIC_Q_DISABLE,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
idev = &lif->ionic->idev;
|
if (!qcq)
|
||||||
dev = lif->ionic->dev;
|
return -ENXIO;
|
||||||
|
|
||||||
dev_dbg(dev, "q_disable.index %d q_disable.qtype %d\n",
|
q = &qcq->q;
|
||||||
ctx.cmd.q_control.index, ctx.cmd.q_control.type);
|
lif = q->lif;
|
||||||
|
|
||||||
if (qcq->flags & IONIC_QCQ_F_INTR) {
|
if (qcq->flags & IONIC_QCQ_F_INTR) {
|
||||||
|
struct ionic_dev *idev = &lif->ionic->idev;
|
||||||
|
|
||||||
cancel_work_sync(&qcq->dim.work);
|
cancel_work_sync(&qcq->dim.work);
|
||||||
ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
|
ionic_intr_mask(idev->intr_ctrl, qcq->intr.index,
|
||||||
IONIC_INTR_MASK_SET);
|
IONIC_INTR_MASK_SET);
|
||||||
|
@ -292,7 +295,17 @@ static int ionic_qcq_disable(struct ionic_qcq *qcq)
|
||||||
napi_disable(&qcq->napi);
|
napi_disable(&qcq->napi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ionic_adminq_post_wait(lif, &ctx);
|
if (send_to_hw) {
|
||||||
|
ctx.cmd.q_control.lif_index = cpu_to_le16(lif->index);
|
||||||
|
ctx.cmd.q_control.type = q->type;
|
||||||
|
ctx.cmd.q_control.index = cpu_to_le32(q->index);
|
||||||
|
dev_dbg(lif->ionic->dev, "q_disable.index %d q_disable.qtype %d\n",
|
||||||
|
ctx.cmd.q_control.index, ctx.cmd.q_control.type);
|
||||||
|
|
||||||
|
err = ionic_adminq_post_wait(lif, &ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
static void ionic_lif_qcq_deinit(struct ionic_lif *lif, struct ionic_qcq *qcq)
|
||||||
|
@ -518,30 +531,55 @@ static int ionic_qcq_alloc(struct ionic_lif *lif, unsigned int type,
|
||||||
goto err_out_free_cq_info;
|
goto err_out_free_cq_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
new->q_size = PAGE_SIZE + (num_descs * desc_size);
|
if (flags & IONIC_QCQ_F_NOTIFYQ) {
|
||||||
new->q_base = dma_alloc_coherent(dev, new->q_size, &new->q_base_pa,
|
int q_size, cq_size;
|
||||||
GFP_KERNEL);
|
|
||||||
if (!new->q_base) {
|
|
||||||
netdev_err(lif->netdev, "Cannot allocate queue DMA memory\n");
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto err_out_free_cq_info;
|
|
||||||
}
|
|
||||||
q_base = PTR_ALIGN(new->q_base, PAGE_SIZE);
|
|
||||||
q_base_pa = ALIGN(new->q_base_pa, PAGE_SIZE);
|
|
||||||
ionic_q_map(&new->q, q_base, q_base_pa);
|
|
||||||
|
|
||||||
new->cq_size = PAGE_SIZE + (num_descs * cq_desc_size);
|
/* q & cq need to be contiguous in case of notifyq */
|
||||||
new->cq_base = dma_alloc_coherent(dev, new->cq_size, &new->cq_base_pa,
|
q_size = ALIGN(num_descs * desc_size, PAGE_SIZE);
|
||||||
GFP_KERNEL);
|
cq_size = ALIGN(num_descs * cq_desc_size, PAGE_SIZE);
|
||||||
if (!new->cq_base) {
|
|
||||||
netdev_err(lif->netdev, "Cannot allocate cq DMA memory\n");
|
new->q_size = PAGE_SIZE + q_size + cq_size;
|
||||||
err = -ENOMEM;
|
new->q_base = dma_alloc_coherent(dev, new->q_size,
|
||||||
goto err_out_free_q;
|
&new->q_base_pa, GFP_KERNEL);
|
||||||
|
if (!new->q_base) {
|
||||||
|
netdev_err(lif->netdev, "Cannot allocate qcq DMA memory\n");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_out_free_cq_info;
|
||||||
|
}
|
||||||
|
q_base = PTR_ALIGN(new->q_base, PAGE_SIZE);
|
||||||
|
q_base_pa = ALIGN(new->q_base_pa, PAGE_SIZE);
|
||||||
|
ionic_q_map(&new->q, q_base, q_base_pa);
|
||||||
|
|
||||||
|
cq_base = PTR_ALIGN(q_base + q_size, PAGE_SIZE);
|
||||||
|
cq_base_pa = ALIGN(new->q_base_pa + q_size, PAGE_SIZE);
|
||||||
|
ionic_cq_map(&new->cq, cq_base, cq_base_pa);
|
||||||
|
ionic_cq_bind(&new->cq, &new->q);
|
||||||
|
} else {
|
||||||
|
new->q_size = PAGE_SIZE + (num_descs * desc_size);
|
||||||
|
new->q_base = dma_alloc_coherent(dev, new->q_size, &new->q_base_pa,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!new->q_base) {
|
||||||
|
netdev_err(lif->netdev, "Cannot allocate queue DMA memory\n");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_out_free_cq_info;
|
||||||
|
}
|
||||||
|
q_base = PTR_ALIGN(new->q_base, PAGE_SIZE);
|
||||||
|
q_base_pa = ALIGN(new->q_base_pa, PAGE_SIZE);
|
||||||
|
ionic_q_map(&new->q, q_base, q_base_pa);
|
||||||
|
|
||||||
|
new->cq_size = PAGE_SIZE + (num_descs * cq_desc_size);
|
||||||
|
new->cq_base = dma_alloc_coherent(dev, new->cq_size, &new->cq_base_pa,
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!new->cq_base) {
|
||||||
|
netdev_err(lif->netdev, "Cannot allocate cq DMA memory\n");
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto err_out_free_q;
|
||||||
|
}
|
||||||
|
cq_base = PTR_ALIGN(new->cq_base, PAGE_SIZE);
|
||||||
|
cq_base_pa = ALIGN(new->cq_base_pa, PAGE_SIZE);
|
||||||
|
ionic_cq_map(&new->cq, cq_base, cq_base_pa);
|
||||||
|
ionic_cq_bind(&new->cq, &new->q);
|
||||||
}
|
}
|
||||||
cq_base = PTR_ALIGN(new->cq_base, PAGE_SIZE);
|
|
||||||
cq_base_pa = ALIGN(new->cq_base_pa, PAGE_SIZE);
|
|
||||||
ionic_cq_map(&new->cq, cq_base, cq_base_pa);
|
|
||||||
ionic_cq_bind(&new->cq, &new->q);
|
|
||||||
|
|
||||||
if (flags & IONIC_QCQ_F_SG) {
|
if (flags & IONIC_QCQ_F_SG) {
|
||||||
new->sg_size = PAGE_SIZE + (num_descs * sg_desc_size);
|
new->sg_size = PAGE_SIZE + (num_descs * sg_desc_size);
|
||||||
|
@ -984,7 +1022,6 @@ static int ionic_lif_addr_del(struct ionic_lif *lif, const u8 *addr)
|
||||||
static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add,
|
static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add,
|
||||||
bool can_sleep)
|
bool can_sleep)
|
||||||
{
|
{
|
||||||
struct ionic *ionic = lif->ionic;
|
|
||||||
struct ionic_deferred_work *work;
|
struct ionic_deferred_work *work;
|
||||||
unsigned int nmfilters;
|
unsigned int nmfilters;
|
||||||
unsigned int nufilters;
|
unsigned int nufilters;
|
||||||
|
@ -994,8 +1031,8 @@ static int ionic_lif_addr(struct ionic_lif *lif, const u8 *addr, bool add,
|
||||||
* here before checking the need for deferral so that we
|
* here before checking the need for deferral so that we
|
||||||
* can return an overflow error to the stack.
|
* can return an overflow error to the stack.
|
||||||
*/
|
*/
|
||||||
nmfilters = le32_to_cpu(ionic->ident.lif.eth.max_mcast_filters);
|
nmfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
|
||||||
nufilters = le32_to_cpu(ionic->ident.lif.eth.max_ucast_filters);
|
nufilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
|
||||||
|
|
||||||
if ((is_multicast_ether_addr(addr) && lif->nmcast < nmfilters))
|
if ((is_multicast_ether_addr(addr) && lif->nmcast < nmfilters))
|
||||||
lif->nmcast++;
|
lif->nmcast++;
|
||||||
|
@ -1124,12 +1161,9 @@ static void ionic_dev_uc_sync(struct net_device *netdev, bool from_ndo)
|
||||||
static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
|
static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
|
||||||
{
|
{
|
||||||
struct ionic_lif *lif = netdev_priv(netdev);
|
struct ionic_lif *lif = netdev_priv(netdev);
|
||||||
struct ionic_identity *ident;
|
|
||||||
unsigned int nfilters;
|
unsigned int nfilters;
|
||||||
unsigned int rx_mode;
|
unsigned int rx_mode;
|
||||||
|
|
||||||
ident = &lif->ionic->ident;
|
|
||||||
|
|
||||||
rx_mode = IONIC_RX_MODE_F_UNICAST;
|
rx_mode = IONIC_RX_MODE_F_UNICAST;
|
||||||
rx_mode |= (netdev->flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0;
|
rx_mode |= (netdev->flags & IFF_MULTICAST) ? IONIC_RX_MODE_F_MULTICAST : 0;
|
||||||
rx_mode |= (netdev->flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0;
|
rx_mode |= (netdev->flags & IFF_BROADCAST) ? IONIC_RX_MODE_F_BROADCAST : 0;
|
||||||
|
@ -1144,7 +1178,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
|
||||||
* to see if we can disable NIC PROMISC
|
* to see if we can disable NIC PROMISC
|
||||||
*/
|
*/
|
||||||
ionic_dev_uc_sync(netdev, from_ndo);
|
ionic_dev_uc_sync(netdev, from_ndo);
|
||||||
nfilters = le32_to_cpu(ident->lif.eth.max_ucast_filters);
|
nfilters = le32_to_cpu(lif->identity->eth.max_ucast_filters);
|
||||||
if (netdev_uc_count(netdev) + 1 > nfilters) {
|
if (netdev_uc_count(netdev) + 1 > nfilters) {
|
||||||
rx_mode |= IONIC_RX_MODE_F_PROMISC;
|
rx_mode |= IONIC_RX_MODE_F_PROMISC;
|
||||||
lif->uc_overflow = true;
|
lif->uc_overflow = true;
|
||||||
|
@ -1156,7 +1190,7 @@ static void ionic_set_rx_mode(struct net_device *netdev, bool from_ndo)
|
||||||
|
|
||||||
/* same for multicast */
|
/* same for multicast */
|
||||||
ionic_dev_uc_sync(netdev, from_ndo);
|
ionic_dev_uc_sync(netdev, from_ndo);
|
||||||
nfilters = le32_to_cpu(ident->lif.eth.max_mcast_filters);
|
nfilters = le32_to_cpu(lif->identity->eth.max_mcast_filters);
|
||||||
if (netdev_mc_count(netdev) > nfilters) {
|
if (netdev_mc_count(netdev) > nfilters) {
|
||||||
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
|
rx_mode |= IONIC_RX_MODE_F_ALLMULTI;
|
||||||
lif->mc_overflow = true;
|
lif->mc_overflow = true;
|
||||||
|
@ -1594,22 +1628,16 @@ static void ionic_lif_rss_deinit(struct ionic_lif *lif)
|
||||||
static void ionic_txrx_disable(struct ionic_lif *lif)
|
static void ionic_txrx_disable(struct ionic_lif *lif)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
int err;
|
int err = 0;
|
||||||
|
|
||||||
if (lif->txqcqs) {
|
if (lif->txqcqs) {
|
||||||
for (i = 0; i < lif->nxqs; i++) {
|
for (i = 0; i < lif->nxqs; i++)
|
||||||
err = ionic_qcq_disable(lif->txqcqs[i]);
|
err = ionic_qcq_disable(lif->txqcqs[i], (err != -ETIMEDOUT));
|
||||||
if (err == -ETIMEDOUT)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lif->rxqcqs) {
|
if (lif->rxqcqs) {
|
||||||
for (i = 0; i < lif->nxqs; i++) {
|
for (i = 0; i < lif->nxqs; i++)
|
||||||
err = ionic_qcq_disable(lif->rxqcqs[i]);
|
err = ionic_qcq_disable(lif->rxqcqs[i], (err != -ETIMEDOUT));
|
||||||
if (err == -ETIMEDOUT)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1761,9 +1789,16 @@ err_out:
|
||||||
|
|
||||||
static int ionic_txrx_enable(struct ionic_lif *lif)
|
static int ionic_txrx_enable(struct ionic_lif *lif)
|
||||||
{
|
{
|
||||||
|
int derr = 0;
|
||||||
int i, err;
|
int i, err;
|
||||||
|
|
||||||
for (i = 0; i < lif->nxqs; i++) {
|
for (i = 0; i < lif->nxqs; i++) {
|
||||||
|
if (!(lif->rxqcqs[i] && lif->txqcqs[i])) {
|
||||||
|
dev_err(lif->ionic->dev, "%s: bad qcq %d\n", __func__, i);
|
||||||
|
err = -ENXIO;
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
ionic_rx_fill(&lif->rxqcqs[i]->q);
|
ionic_rx_fill(&lif->rxqcqs[i]->q);
|
||||||
err = ionic_qcq_enable(lif->rxqcqs[i]);
|
err = ionic_qcq_enable(lif->rxqcqs[i]);
|
||||||
if (err)
|
if (err)
|
||||||
|
@ -1771,8 +1806,7 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
|
||||||
|
|
||||||
err = ionic_qcq_enable(lif->txqcqs[i]);
|
err = ionic_qcq_enable(lif->txqcqs[i]);
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err != -ETIMEDOUT)
|
derr = ionic_qcq_disable(lif->rxqcqs[i], (err != -ETIMEDOUT));
|
||||||
ionic_qcq_disable(lif->rxqcqs[i]);
|
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1781,12 +1815,8 @@ static int ionic_txrx_enable(struct ionic_lif *lif)
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
while (i--) {
|
while (i--) {
|
||||||
err = ionic_qcq_disable(lif->txqcqs[i]);
|
derr = ionic_qcq_disable(lif->txqcqs[i], (derr != -ETIMEDOUT));
|
||||||
if (err == -ETIMEDOUT)
|
derr = ionic_qcq_disable(lif->rxqcqs[i], (derr != -ETIMEDOUT));
|
||||||
break;
|
|
||||||
err = ionic_qcq_disable(lif->rxqcqs[i]);
|
|
||||||
if (err == -ETIMEDOUT)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -2391,7 +2421,12 @@ int ionic_lif_alloc(struct ionic *ionic)
|
||||||
|
|
||||||
lif->identity = lid;
|
lif->identity = lid;
|
||||||
lif->lif_type = IONIC_LIF_TYPE_CLASSIC;
|
lif->lif_type = IONIC_LIF_TYPE_CLASSIC;
|
||||||
ionic_lif_identify(ionic, lif->lif_type, lif->identity);
|
err = ionic_lif_identify(ionic, lif->lif_type, lif->identity);
|
||||||
|
if (err) {
|
||||||
|
dev_err(ionic->dev, "Cannot identify type %d: %d\n",
|
||||||
|
lif->lif_type, err);
|
||||||
|
goto err_out_free_netdev;
|
||||||
|
}
|
||||||
lif->netdev->min_mtu = max_t(unsigned int, ETH_MIN_MTU,
|
lif->netdev->min_mtu = max_t(unsigned int, ETH_MIN_MTU,
|
||||||
le32_to_cpu(lif->identity->eth.min_frame_size));
|
le32_to_cpu(lif->identity->eth.min_frame_size));
|
||||||
lif->netdev->max_mtu =
|
lif->netdev->max_mtu =
|
||||||
|
@ -2522,7 +2557,15 @@ static void ionic_lif_handle_fw_up(struct ionic_lif *lif)
|
||||||
dev_info(ionic->dev, "FW Up: restarting LIFs\n");
|
dev_info(ionic->dev, "FW Up: restarting LIFs\n");
|
||||||
|
|
||||||
ionic_init_devinfo(ionic);
|
ionic_init_devinfo(ionic);
|
||||||
ionic_port_init(ionic);
|
err = ionic_identify(ionic);
|
||||||
|
if (err)
|
||||||
|
goto err_out;
|
||||||
|
err = ionic_port_identify(ionic);
|
||||||
|
if (err)
|
||||||
|
goto err_out;
|
||||||
|
err = ionic_port_init(ionic);
|
||||||
|
if (err)
|
||||||
|
goto err_out;
|
||||||
err = ionic_qcqs_alloc(lif);
|
err = ionic_qcqs_alloc(lif);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
|
@ -64,6 +64,8 @@ static const char *ionic_error_to_str(enum ionic_status_code code)
|
||||||
return "IONIC_RC_ERROR";
|
return "IONIC_RC_ERROR";
|
||||||
case IONIC_RC_ERDMA:
|
case IONIC_RC_ERDMA:
|
||||||
return "IONIC_RC_ERDMA";
|
return "IONIC_RC_ERDMA";
|
||||||
|
case IONIC_RC_EBAD_FW:
|
||||||
|
return "IONIC_RC_EBAD_FW";
|
||||||
default:
|
default:
|
||||||
return "IONIC_RC_UNKNOWN";
|
return "IONIC_RC_UNKNOWN";
|
||||||
}
|
}
|
||||||
|
@ -429,17 +431,23 @@ int ionic_identify(struct ionic *ionic)
|
||||||
sz = min(sizeof(ident->dev), sizeof(idev->dev_cmd_regs->data));
|
sz = min(sizeof(ident->dev), sizeof(idev->dev_cmd_regs->data));
|
||||||
memcpy_fromio(&ident->dev, &idev->dev_cmd_regs->data, sz);
|
memcpy_fromio(&ident->dev, &idev->dev_cmd_regs->data, sz);
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&ionic->dev_cmd_lock);
|
mutex_unlock(&ionic->dev_cmd_lock);
|
||||||
|
|
||||||
if (err)
|
if (err) {
|
||||||
goto err_out_unmap;
|
dev_err(ionic->dev, "Cannot identify ionic: %dn", err);
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
ionic_debugfs_add_ident(ionic);
|
err = ionic_lif_identify(ionic, IONIC_LIF_TYPE_CLASSIC,
|
||||||
|
&ionic->ident.lif);
|
||||||
|
if (err) {
|
||||||
|
dev_err(ionic->dev, "Cannot identify LIFs: %d\n", err);
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_out_unmap:
|
err_out:
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue