]> git.baikalelectronics.ru Git - kernel.git/commitdiff
octeontx2-pf: cn10k: Get max mtu supported from admin function
authorHariprasad Kelam <hkelam@marvell.com>
Thu, 11 Feb 2021 15:58:31 +0000 (21:28 +0530)
committerDavid S. Miller <davem@davemloft.net>
Thu, 11 Feb 2021 22:55:03 +0000 (14:55 -0800)
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>
drivers/net/ethernet/marvell/octeontx2/nic/cn10k.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_pf.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_txrx.h
drivers/net/ethernet/marvell/octeontx2/nic/otx2_vf.c

index d6ca809edaed7f1d5999b05f50d3409f91c63088..9ec0313f13fc5719281d19b625a1f4c19a281ac4 100644 (file)
@@ -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;
index 2779802eed84c6e7907f052225515c4349f1c6c4..cf7875d51d879325cd79f7a785de58caf1b343a0 100644 (file)
@@ -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);
@@ -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);
@@ -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,               \
index 51aaa6ae0fd37c7c8e89f6ff67d1165f602efd31..4c472646a0ac3e5ae269ac43dd64ac9347b07787 100644 (file)
@@ -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 */
index f87cfcfc2832591f5a21acf33bba63e62dfa1377..53ab1814d74b30f30ef881526e49a46cc5483083 100644 (file)
@@ -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;
@@ -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 */
@@ -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) {
index 59a7bd88d907ba6b413c32fd134c54b685d987d3..3f778fc054b59a76d6eb453b9e60db802f3176e2 100644 (file)
@@ -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 */
@@ -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;
        }
@@ -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);
index d2b26b3357f3df6b27587c2850a05bdbcae66576..52486c1f0973ae19540e401855027d93fdc0f440 100644 (file)
@@ -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
index 31e03253e61256ceaf8623079dc9a70fadaca7d6..085be90a03eb14dc10e7d2749164ac85b64e1b03 100644 (file)
@@ -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);