Skip to content

Commit

Permalink
octeontx2-pf: cn10k: Get max mtu supported from admin function
Browse files Browse the repository at this point in the history
CN10K supports max MTU of 16K on LMAC links and 64k on LBK
links and Octeontx2 silicon supports 9K mtu on both links.
Get the same from nix_get_hw_info mbox message in netdev probe.

This patch also calculates receive buffer size required based
on the MTU set.

Signed-off-by: Hariprasad Kelam <hkelam@marvell.com>
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Geetha sowjanya <gakula@marvell.com>
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Hariprasad Kelam authored and David S. Miller committed Feb 11, 2021
1 parent 6e54e1c commit ab58a41
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 18 deletions.
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ int cn10k_sq_aq_init(void *dev, u16 qidx, u16 sqb_aura)
/* Only one SMQ is allocated, map all SQ's to that SMQ */
aq->sq.smq = pfvf->hw.txschq_list[NIX_TXSCH_LVL_SMQ][0];
/* FIXME: set based on NIX_AF_DWRR_RPM_MTU*/
aq->sq.smq_rr_weight = OTX2_MAX_MTU;
aq->sq.smq_rr_weight = pfvf->netdev->mtu;
aq->sq.default_chan = pfvf->hw.tx_chan_base;
aq->sq.sqe_stype = NIX_STYPE_STF; /* Cache SQB */
aq->sq.sqb_aura = sqb_aura;
Expand Down
45 changes: 42 additions & 3 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ int otx2_hw_set_mtu(struct otx2_nic *pfvf, int mtu)
return -ENOMEM;
}

pfvf->max_frs = mtu + OTX2_ETH_HLEN;
req->maxlen = pfvf->max_frs;

err = otx2_sync_mbox_msg(&pfvf->mbox);
Expand Down Expand Up @@ -606,8 +605,8 @@ int otx2_txschq_config(struct otx2_nic *pfvf, int lvl)
/* Set topology e.t.c configuration */
if (lvl == NIX_TXSCH_LVL_SMQ) {
req->reg[0] = NIX_AF_SMQX_CFG(schq);
req->regval[0] = ((OTX2_MAX_MTU + OTX2_ETH_HLEN) << 8) |
OTX2_MIN_MTU;
req->regval[0] = ((pfvf->netdev->max_mtu + OTX2_ETH_HLEN) << 8)
| OTX2_MIN_MTU;

req->regval[0] |= (0x20ULL << 51) | (0x80ULL << 39) |
(0x2ULL << 36);
Expand Down Expand Up @@ -1637,6 +1636,46 @@ void otx2_set_cints_affinity(struct otx2_nic *pfvf)
}
}

u16 otx2_get_max_mtu(struct otx2_nic *pfvf)
{
struct nix_hw_info *rsp;
struct msg_req *req;
u16 max_mtu;
int rc;

mutex_lock(&pfvf->mbox.lock);

req = otx2_mbox_alloc_msg_nix_get_hw_info(&pfvf->mbox);
if (!req) {
rc = -ENOMEM;
goto out;
}

rc = otx2_sync_mbox_msg(&pfvf->mbox);
if (!rc) {
rsp = (struct nix_hw_info *)
otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);

/* HW counts VLAN insertion bytes (8 for double tag)
* irrespective of whether SQE is requesting to insert VLAN
* in the packet or not. Hence these 8 bytes have to be
* discounted from max packet size otherwise HW will throw
* SMQ errors
*/
max_mtu = rsp->max_mtu - 8 - OTX2_ETH_HLEN;
}

out:
mutex_unlock(&pfvf->mbox.lock);
if (rc) {
dev_warn(pfvf->dev,
"Failed to get MTU from hardware setting default value(1500)\n");
max_mtu = 1500;
}
return max_mtu;
}
EXPORT_SYMBOL(otx2_get_max_mtu);

#define M(_name, _id, _fn_name, _req_type, _rsp_type) \
int __weak \
otx2_mbox_up_handler_ ## _fn_name(struct otx2_nic *pfvf, \
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -798,5 +798,5 @@ int otx2_del_macfilter(struct net_device *netdev, const u8 *mac);
int otx2_add_macfilter(struct net_device *netdev, const u8 *mac);
int otx2_enable_rxvlan(struct otx2_nic *pf, bool enable);
int otx2_install_rxvlan_offload_flow(struct otx2_nic *pfvf);

u16 otx2_get_max_mtu(struct otx2_nic *pfvf);
#endif /* OTX2_COMMON_H */
35 changes: 31 additions & 4 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1288,6 +1288,33 @@ static void otx2_free_sq_res(struct otx2_nic *pf)
}
}

static int otx2_get_rbuf_size(struct otx2_nic *pf, int mtu)
{
int frame_size;
int total_size;
int rbuf_size;

/* The data transferred by NIX to memory consists of actual packet
* plus additional data which has timestamp and/or EDSA/HIGIG2
* headers if interface is configured in corresponding modes.
* NIX transfers entire data using 6 segments/buffers and writes
* a CQE_RX descriptor with those segment addresses. First segment
* has additional data prepended to packet. Also software omits a
* headroom of 128 bytes and sizeof(struct skb_shared_info) in
* each segment. Hence the total size of memory needed
* to receive a packet with 'mtu' is:
* frame size = mtu + additional data;
* memory = frame_size + (headroom + struct skb_shared_info size) * 6;
* each receive buffer size = memory / 6;
*/
frame_size = mtu + OTX2_ETH_HLEN + OTX2_HW_TIMESTAMP_LEN;
total_size = frame_size + (OTX2_HEAD_ROOM +
OTX2_DATA_ALIGN(sizeof(struct skb_shared_info))) * 6;
rbuf_size = total_size / 6;

return ALIGN(rbuf_size, 2048);
}

static int otx2_init_hw_resources(struct otx2_nic *pf)
{
struct nix_lf_free_req *free_req;
Expand All @@ -1304,9 +1331,9 @@ static int otx2_init_hw_resources(struct otx2_nic *pf)
hw->sqpool_cnt = hw->tx_queues;
hw->pool_cnt = hw->rqpool_cnt + hw->sqpool_cnt;

/* Get the size of receive buffers to allocate */
pf->rbsize = RCV_FRAG_LEN(OTX2_HW_TIMESTAMP_LEN + pf->netdev->mtu +
OTX2_ETH_HLEN);
pf->max_frs = pf->netdev->mtu + OTX2_ETH_HLEN + OTX2_HW_TIMESTAMP_LEN;

pf->rbsize = otx2_get_rbuf_size(pf, pf->netdev->mtu);

mutex_lock(&mbox->lock);
/* NPA init */
Expand Down Expand Up @@ -2429,7 +2456,7 @@ static int otx2_probe(struct pci_dev *pdev, const struct pci_device_id *id)

/* MTU range: 64 - 9190 */
netdev->min_mtu = OTX2_MIN_MTU;
netdev->max_mtu = OTX2_MAX_MTU;
netdev->max_mtu = otx2_get_max_mtu(pf);

err = register_netdev(netdev);
if (err) {
Expand Down
28 changes: 21 additions & 7 deletions drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,11 @@ static bool otx2_check_rcv_errors(struct otx2_nic *pfvf,
/* For now ignore all the NPC parser errors and
* pass the packets to stack.
*/
if (cqe->sg.segs == 1)
return false;
return false;
}

/* If RXALL is enabled pass on packets to stack. */
if (cqe->sg.segs == 1 && (pfvf->netdev->features & NETIF_F_RXALL))
if (pfvf->netdev->features & NETIF_F_RXALL)
return false;

/* Free buffer back to pool */
Expand All @@ -277,9 +276,14 @@ static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf,
struct nix_cqe_rx_s *cqe)
{
struct nix_rx_parse_s *parse = &cqe->parse;
struct nix_rx_sg_s *sg = &cqe->sg;
struct sk_buff *skb = NULL;
void *end, *start;
u64 *seg_addr;
u16 *seg_size;
int seg;

if (unlikely(parse->errlev || parse->errcode || cqe->sg.segs > 1)) {
if (unlikely(parse->errlev || parse->errcode)) {
if (otx2_check_rcv_errors(pfvf, cqe, cq->cq_idx))
return;
}
Expand All @@ -288,9 +292,19 @@ static void otx2_rcv_pkt_handler(struct otx2_nic *pfvf,
if (unlikely(!skb))
return;

otx2_skb_add_frag(pfvf, skb, cqe->sg.seg_addr, cqe->sg.seg_size, parse);
cq->pool_ptrs++;

start = (void *)sg;
end = start + ((cqe->parse.desc_sizem1 + 1) * 16);
while (start < end) {
sg = (struct nix_rx_sg_s *)start;
seg_addr = &sg->seg_addr;
seg_size = (void *)sg;
for (seg = 0; seg < sg->segs; seg++, seg_addr++) {
otx2_skb_add_frag(pfvf, skb, *seg_addr, seg_size[seg],
parse);
cq->pool_ptrs++;
}
start += sizeof(*sg);
}
otx2_set_rxhash(pfvf, cqe, skb);

skb_record_rx_queue(skb, cq->cq_idx);
Expand Down
1 change: 0 additions & 1 deletion drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

#define OTX2_ETH_HLEN (VLAN_ETH_HLEN + VLAN_HLEN)
#define OTX2_MIN_MTU 64
#define OTX2_MAX_MTU (9212 - OTX2_ETH_HLEN)

#define OTX2_MAX_GSO_SEGS 255
#define OTX2_MAX_FRAGS_IN_SQE 9
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,7 @@ static int otx2vf_probe(struct pci_dev *pdev, const struct pci_device_id *id)

/* MTU range: 68 - 9190 */
netdev->min_mtu = OTX2_MIN_MTU;
netdev->max_mtu = OTX2_MAX_MTU;
netdev->max_mtu = otx2_get_max_mtu(vf);

INIT_WORK(&vf->reset_task, otx2vf_reset_task);

Expand Down

0 comments on commit ab58a41

Please sign in to comment.