Commit a59cf619 authored by David S. Miller's avatar David S. Miller

Merge branch 'Fix-bugs-in-Octeontx2-netdev-driver'

Geetha sowjanya says:

====================
Fix bugs in Octeontx2 netdev driver

In existing Octeontx2 network drivers code has issues
like stale entries in broadcast replication list, missing
L3TYPE for IPv6 frames, running tx queues on error and
race condition in mbox reset.
This patch set fixes the above issues.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 03e7e72c 66a5209b
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
static const u16 msgs_offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN); static const u16 msgs_offset = ALIGN(sizeof(struct mbox_hdr), MBOX_MSG_ALIGN);
void otx2_mbox_reset(struct otx2_mbox *mbox, int devid) void __otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
{ {
void *hw_mbase = mbox->hwbase + (devid * MBOX_SIZE); void *hw_mbase = mbox->hwbase + (devid * MBOX_SIZE);
struct otx2_mbox_dev *mdev = &mbox->dev[devid]; struct otx2_mbox_dev *mdev = &mbox->dev[devid];
...@@ -26,13 +26,21 @@ void otx2_mbox_reset(struct otx2_mbox *mbox, int devid) ...@@ -26,13 +26,21 @@ void otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
tx_hdr = hw_mbase + mbox->tx_start; tx_hdr = hw_mbase + mbox->tx_start;
rx_hdr = hw_mbase + mbox->rx_start; rx_hdr = hw_mbase + mbox->rx_start;
spin_lock(&mdev->mbox_lock);
mdev->msg_size = 0; mdev->msg_size = 0;
mdev->rsp_size = 0; mdev->rsp_size = 0;
tx_hdr->num_msgs = 0; tx_hdr->num_msgs = 0;
tx_hdr->msg_size = 0; tx_hdr->msg_size = 0;
rx_hdr->num_msgs = 0; rx_hdr->num_msgs = 0;
rx_hdr->msg_size = 0; rx_hdr->msg_size = 0;
}
EXPORT_SYMBOL(__otx2_mbox_reset);
void otx2_mbox_reset(struct otx2_mbox *mbox, int devid)
{
struct otx2_mbox_dev *mdev = &mbox->dev[devid];
spin_lock(&mdev->mbox_lock);
__otx2_mbox_reset(mbox, devid);
spin_unlock(&mdev->mbox_lock); spin_unlock(&mdev->mbox_lock);
} }
EXPORT_SYMBOL(otx2_mbox_reset); EXPORT_SYMBOL(otx2_mbox_reset);
......
...@@ -93,6 +93,7 @@ struct mbox_msghdr { ...@@ -93,6 +93,7 @@ struct mbox_msghdr {
}; };
void otx2_mbox_reset(struct otx2_mbox *mbox, int devid); void otx2_mbox_reset(struct otx2_mbox *mbox, int devid);
void __otx2_mbox_reset(struct otx2_mbox *mbox, int devid);
void otx2_mbox_destroy(struct otx2_mbox *mbox); void otx2_mbox_destroy(struct otx2_mbox *mbox);
int otx2_mbox_init(struct otx2_mbox *mbox, void __force *hwbase, int otx2_mbox_init(struct otx2_mbox *mbox, void __force *hwbase,
struct pci_dev *pdev, void __force *reg_base, struct pci_dev *pdev, void __force *reg_base,
......
...@@ -463,6 +463,7 @@ void rvu_nix_freemem(struct rvu *rvu); ...@@ -463,6 +463,7 @@ void rvu_nix_freemem(struct rvu *rvu);
int rvu_get_nixlf_count(struct rvu *rvu); int rvu_get_nixlf_count(struct rvu *rvu);
void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int npalf); void rvu_nix_lf_teardown(struct rvu *rvu, u16 pcifunc, int blkaddr, int npalf);
int nix_get_nixlf(struct rvu *rvu, u16 pcifunc, int *nixlf, int *nix_blkaddr); int nix_get_nixlf(struct rvu *rvu, u16 pcifunc, int *nixlf, int *nix_blkaddr);
int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add);
/* NPC APIs */ /* NPC APIs */
int rvu_npc_init(struct rvu *rvu); int rvu_npc_init(struct rvu *rvu);
...@@ -477,7 +478,7 @@ void rvu_npc_disable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf); ...@@ -477,7 +478,7 @@ void rvu_npc_disable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_enable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf); void rvu_npc_enable_promisc_entry(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc, void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
int nixlf, u64 chan); int nixlf, u64 chan);
void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc); void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable);
int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf); int rvu_npc_update_rxvlan(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf); void rvu_npc_disable_mcam_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf); void rvu_npc_disable_default_entries(struct rvu *rvu, u16 pcifunc, int nixlf);
......
...@@ -17,7 +17,6 @@ ...@@ -17,7 +17,6 @@
#include "npc.h" #include "npc.h"
#include "cgx.h" #include "cgx.h"
static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add);
static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req, static int rvu_nix_get_bpid(struct rvu *rvu, struct nix_bp_cfg_req *req,
int type, int chan_id); int type, int chan_id);
...@@ -2020,7 +2019,7 @@ static int nix_update_mce_list(struct nix_mce_list *mce_list, ...@@ -2020,7 +2019,7 @@ static int nix_update_mce_list(struct nix_mce_list *mce_list,
return 0; return 0;
} }
static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add) int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
{ {
int err = 0, idx, next_idx, last_idx; int err = 0, idx, next_idx, last_idx;
struct nix_mce_list *mce_list; struct nix_mce_list *mce_list;
...@@ -2065,7 +2064,7 @@ static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add) ...@@ -2065,7 +2064,7 @@ static int nix_update_bcast_mce_list(struct rvu *rvu, u16 pcifunc, bool add)
/* Disable MCAM entry in NPC */ /* Disable MCAM entry in NPC */
if (!mce_list->count) { if (!mce_list->count) {
rvu_npc_disable_bcast_entry(rvu, pcifunc); rvu_npc_enable_bcast_entry(rvu, pcifunc, false);
goto end; goto end;
} }
......
...@@ -530,7 +530,7 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc, ...@@ -530,7 +530,7 @@ void rvu_npc_install_bcast_match_entry(struct rvu *rvu, u16 pcifunc,
NIX_INTF_RX, &entry, true); NIX_INTF_RX, &entry, true);
} }
void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc) void rvu_npc_enable_bcast_entry(struct rvu *rvu, u16 pcifunc, bool enable)
{ {
struct npc_mcam *mcam = &rvu->hw->mcam; struct npc_mcam *mcam = &rvu->hw->mcam;
int blkaddr, index; int blkaddr, index;
...@@ -543,7 +543,7 @@ void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc) ...@@ -543,7 +543,7 @@ void rvu_npc_disable_bcast_entry(struct rvu *rvu, u16 pcifunc)
pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK; pcifunc = pcifunc & ~RVU_PFVF_FUNC_MASK;
index = npc_get_nixlf_mcam_index(mcam, pcifunc, 0, NIXLF_BCAST_ENTRY); index = npc_get_nixlf_mcam_index(mcam, pcifunc, 0, NIXLF_BCAST_ENTRY);
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false); npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
} }
void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf, void rvu_npc_update_flowkey_alg_idx(struct rvu *rvu, u16 pcifunc, int nixlf,
...@@ -622,23 +622,35 @@ static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc, ...@@ -622,23 +622,35 @@ static void npc_enadis_default_entries(struct rvu *rvu, u16 pcifunc,
nixlf, NIXLF_UCAST_ENTRY); nixlf, NIXLF_UCAST_ENTRY);
npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable); npc_enable_mcam_entry(rvu, mcam, blkaddr, index, enable);
/* For PF, ena/dis promisc and bcast MCAM match entries */ /* For PF, ena/dis promisc and bcast MCAM match entries.
if (pcifunc & RVU_PFVF_FUNC_MASK) * For VFs add/delete from bcast list when RX multicast
* feature is present.
*/
if (pcifunc & RVU_PFVF_FUNC_MASK && !rvu->hw->cap.nix_rx_multicast)
return; return;
/* For bcast, enable/disable only if it's action is not /* For bcast, enable/disable only if it's action is not
* packet replication, incase if action is replication * packet replication, incase if action is replication
* then this PF's nixlf is removed from bcast replication * then this PF/VF's nixlf is removed from bcast replication
* list. * list.
*/ */
index = npc_get_nixlf_mcam_index(mcam, pcifunc, index = npc_get_nixlf_mcam_index(mcam, pcifunc & ~RVU_PFVF_FUNC_MASK,
nixlf, NIXLF_BCAST_ENTRY); nixlf, NIXLF_BCAST_ENTRY);
bank = npc_get_bank(mcam, index); bank = npc_get_bank(mcam, index);
*(u64 *)&action = rvu_read64(rvu, blkaddr, *(u64 *)&action = rvu_read64(rvu, blkaddr,
NPC_AF_MCAMEX_BANKX_ACTION(index & (mcam->banksize - 1), bank)); NPC_AF_MCAMEX_BANKX_ACTION(index & (mcam->banksize - 1), bank));
if (action.op != NIX_RX_ACTIONOP_MCAST)
/* VFs will not have BCAST entry */
if (action.op != NIX_RX_ACTIONOP_MCAST &&
!(pcifunc & RVU_PFVF_FUNC_MASK)) {
npc_enable_mcam_entry(rvu, mcam, npc_enable_mcam_entry(rvu, mcam,
blkaddr, index, enable); blkaddr, index, enable);
} else {
nix_update_bcast_mce_list(rvu, pcifunc, enable);
/* Enable PF's BCAST entry for packet replication */
rvu_npc_enable_bcast_entry(rvu, pcifunc, enable);
}
if (enable) if (enable)
rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf); rvu_npc_enable_promisc_entry(rvu, pcifunc, nixlf);
else else
......
...@@ -370,8 +370,8 @@ static int otx2_forward_vf_mbox_msgs(struct otx2_nic *pf, ...@@ -370,8 +370,8 @@ static int otx2_forward_vf_mbox_msgs(struct otx2_nic *pf,
dst_mbox = &pf->mbox; dst_mbox = &pf->mbox;
dst_size = dst_mbox->mbox.tx_size - dst_size = dst_mbox->mbox.tx_size -
ALIGN(sizeof(*mbox_hdr), MBOX_MSG_ALIGN); ALIGN(sizeof(*mbox_hdr), MBOX_MSG_ALIGN);
/* Check if msgs fit into destination area */ /* Check if msgs fit into destination area and has valid size */
if (mbox_hdr->msg_size > dst_size) if (mbox_hdr->msg_size > dst_size || !mbox_hdr->msg_size)
return -EINVAL; return -EINVAL;
dst_mdev = &dst_mbox->mbox.dev[0]; dst_mdev = &dst_mbox->mbox.dev[0];
...@@ -526,10 +526,10 @@ static void otx2_pfvf_mbox_up_handler(struct work_struct *work) ...@@ -526,10 +526,10 @@ static void otx2_pfvf_mbox_up_handler(struct work_struct *work)
end: end:
offset = mbox->rx_start + msg->next_msgoff; offset = mbox->rx_start + msg->next_msgoff;
if (mdev->msgs_acked == (vf_mbox->up_num_msgs - 1))
__otx2_mbox_reset(mbox, 0);
mdev->msgs_acked++; mdev->msgs_acked++;
} }
otx2_mbox_reset(mbox, vf_idx);
} }
static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq) static irqreturn_t otx2_pfvf_mbox_intr_handler(int irq, void *pf_irq)
...@@ -803,10 +803,11 @@ static void otx2_pfaf_mbox_handler(struct work_struct *work) ...@@ -803,10 +803,11 @@ static void otx2_pfaf_mbox_handler(struct work_struct *work)
msg = (struct mbox_msghdr *)(mdev->mbase + offset); msg = (struct mbox_msghdr *)(mdev->mbase + offset);
otx2_process_pfaf_mbox_msg(pf, msg); otx2_process_pfaf_mbox_msg(pf, msg);
offset = mbox->rx_start + msg->next_msgoff; offset = mbox->rx_start + msg->next_msgoff;
if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
__otx2_mbox_reset(mbox, 0);
mdev->msgs_acked++; mdev->msgs_acked++;
} }
otx2_mbox_reset(mbox, 0);
} }
static void otx2_handle_link_event(struct otx2_nic *pf) static void otx2_handle_link_event(struct otx2_nic *pf)
...@@ -1560,10 +1561,13 @@ int otx2_open(struct net_device *netdev) ...@@ -1560,10 +1561,13 @@ int otx2_open(struct net_device *netdev)
err = otx2_rxtx_enable(pf, true); err = otx2_rxtx_enable(pf, true);
if (err) if (err)
goto err_free_cints; goto err_tx_stop_queues;
return 0; return 0;
err_tx_stop_queues:
netif_tx_stop_all_queues(netdev);
netif_carrier_off(netdev);
err_free_cints: err_free_cints:
otx2_free_cints(pf, qidx); otx2_free_cints(pf, qidx);
vec = pci_irq_vector(pf->pdev, vec = pci_irq_vector(pf->pdev,
......
...@@ -524,6 +524,7 @@ static void otx2_sqe_add_hdr(struct otx2_nic *pfvf, struct otx2_snd_queue *sq, ...@@ -524,6 +524,7 @@ static void otx2_sqe_add_hdr(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
sqe_hdr->ol3type = NIX_SENDL3TYPE_IP4_CKSUM; sqe_hdr->ol3type = NIX_SENDL3TYPE_IP4_CKSUM;
} else if (skb->protocol == htons(ETH_P_IPV6)) { } else if (skb->protocol == htons(ETH_P_IPV6)) {
proto = ipv6_hdr(skb)->nexthdr; proto = ipv6_hdr(skb)->nexthdr;
sqe_hdr->ol3type = NIX_SENDL3TYPE_IP6;
} }
if (proto == IPPROTO_TCP) if (proto == IPPROTO_TCP)
......
...@@ -99,10 +99,10 @@ static void otx2vf_vfaf_mbox_handler(struct work_struct *work) ...@@ -99,10 +99,10 @@ static void otx2vf_vfaf_mbox_handler(struct work_struct *work)
msg = (struct mbox_msghdr *)(mdev->mbase + offset); msg = (struct mbox_msghdr *)(mdev->mbase + offset);
otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg); otx2vf_process_vfaf_mbox_msg(af_mbox->pfvf, msg);
offset = mbox->rx_start + msg->next_msgoff; offset = mbox->rx_start + msg->next_msgoff;
if (mdev->msgs_acked == (af_mbox->num_msgs - 1))
__otx2_mbox_reset(mbox, 0);
mdev->msgs_acked++; mdev->msgs_acked++;
} }
otx2_mbox_reset(mbox, 0);
} }
static int otx2vf_process_mbox_msg_up(struct otx2_nic *vf, static int otx2vf_process_mbox_msg_up(struct otx2_nic *vf,
......
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