This patch series address the fix to use multiqueue start/stop APIs and Add Rx IP and TCP checksum offload
Changes:
========
V0 -> V1:
- Remove chip SKU check conditionals
- Update the changes description
Raju Lakkaraju (2):
net: lan743x: Fix to use multiqueue start/stop APIs
net: lan743x: Add support for Rx IP & TCP checksum offload
drivers/net/ethernet/microchip/lan743x_main.c | 64 +++++++++++--------
drivers/net/ethernet/microchip/lan743x_main.h | 10 ++-
2 files changed, 45 insertions(+), 29 deletions(-)
--
2.25.1
Add Rx IP and TCP checksum offload
Signed-off-by: Raju Lakkaraju <[email protected]>
---
drivers/net/ethernet/microchip/lan743x_main.c | 14 +++++++++++++-
drivers/net/ethernet/microchip/lan743x_main.h | 5 +++++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c
index 3f4e1ab63f8a..59441f06ff45 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.c
+++ b/drivers/net/ethernet/microchip/lan743x_main.c
@@ -1585,6 +1585,9 @@ static void lan743x_rfe_set_multicast(struct lan743x_adapter *adapter)
rfctl |= RFE_CTL_AM_;
}
+ if (netdev->features & NETIF_F_RXCSUM)
+ rfctl |= RFE_CTL_IP_COE_ | RFE_CTL_TCP_UDP_COE_;
+
memset(hash_table, 0, DP_SEL_VHF_HASH_LEN * sizeof(u32));
if (netdev_mc_count(netdev)) {
struct netdev_hw_addr *ha;
@@ -2547,6 +2550,7 @@ static int lan743x_rx_process_buffer(struct lan743x_rx *rx)
int result = RX_PROCESS_RESULT_NOTHING_TO_DO;
struct lan743x_rx_buffer_info *buffer_info;
int frame_length, buffer_length;
+ bool is_ice, is_tce, is_icsm;
int extension_index = -1;
bool is_last, is_first;
struct sk_buff *skb;
@@ -2593,6 +2597,9 @@ static int lan743x_rx_process_buffer(struct lan743x_rx *rx)
frame_length =
RX_DESC_DATA0_FRAME_LENGTH_GET_(le32_to_cpu(descriptor->data0));
buffer_length = buffer_info->buffer_length;
+ is_ice = descriptor->data1 & RX_DESC_DATA1_STATUS_ICE_;
+ is_tce = descriptor->data1 & RX_DESC_DATA1_STATUS_TCE_;
+ is_icsm = descriptor->data1 & RX_DESC_DATA1_STATUS_ICSM_;
netdev_dbg(netdev, "%s%schunk: %d/%d",
is_first ? "first " : " ",
@@ -2661,6 +2668,10 @@ static int lan743x_rx_process_buffer(struct lan743x_rx *rx)
if (is_last && rx->skb_head) {
rx->skb_head->protocol = eth_type_trans(rx->skb_head,
rx->adapter->netdev);
+ if (rx->adapter->netdev->features & NETIF_F_RXCSUM) {
+ if (!is_ice && !is_tce && !is_icsm)
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ }
netdev_dbg(netdev, "sending %d byte frame to OS",
rx->skb_head->len);
napi_gro_receive(&rx->napi, rx->skb_head);
@@ -3383,7 +3394,8 @@ static int lan743x_pcidev_probe(struct pci_dev *pdev,
adapter->netdev->netdev_ops = &lan743x_netdev_ops;
adapter->netdev->ethtool_ops = &lan743x_ethtool_ops;
- adapter->netdev->features = NETIF_F_SG | NETIF_F_TSO | NETIF_F_HW_CSUM;
+ adapter->netdev->features = NETIF_F_SG | NETIF_F_TSO |
+ NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
adapter->netdev->hw_features = adapter->netdev->features;
/* carrier off reporting is important to ethtool even BEFORE open */
diff --git a/drivers/net/ethernet/microchip/lan743x_main.h b/drivers/net/ethernet/microchip/lan743x_main.h
index 58eb7abf976b..67877d3b6dd9 100644
--- a/drivers/net/ethernet/microchip/lan743x_main.h
+++ b/drivers/net/ethernet/microchip/lan743x_main.h
@@ -266,6 +266,8 @@
#define RFE_ADDR_FILT_LO(x) (0x404 + (8 * (x)))
#define RFE_CTL (0x508)
+#define RFE_CTL_TCP_UDP_COE_ BIT(12)
+#define RFE_CTL_IP_COE_ BIT(11)
#define RFE_CTL_AB_ BIT(10)
#define RFE_CTL_AM_ BIT(9)
#define RFE_CTL_AU_ BIT(8)
@@ -1121,6 +1123,9 @@ struct lan743x_tx_buffer_info {
(((data0) & RX_DESC_DATA0_FRAME_LENGTH_MASK_) >> 16)
#define RX_DESC_DATA0_EXT_ (0x00004000)
#define RX_DESC_DATA0_BUF_LENGTH_MASK_ (0x00003FFF)
+#define RX_DESC_DATA1_STATUS_ICE_ (0x00020000)
+#define RX_DESC_DATA1_STATUS_TCE_ (0x00010000)
+#define RX_DESC_DATA1_STATUS_ICSM_ (0x00000001)
#define RX_DESC_DATA2_TS_NS_MASK_ (0x3FFFFFFF)
#if ((NET_IP_ALIGN != 0) && (NET_IP_ALIGN != 2))
--
2.25.1
Hi Raju,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/intel-lab-lkp/linux/commits/Raju-Lakkaraju/net-lan743x-Fix-to-use-multiqueue-start-stop-APIs/20220907-143456
base: https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 2786bcff28bd88955fc61adf9cb7370fbc182bad
config: sparc-randconfig-s043-20220907 (https://download.01.org/0day-ci/archive/20220908/[email protected]/config)
compiler: sparc-linux-gcc (GCC) 12.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel-lab-lkp/linux/commit/d965e2dd24f617d68ded6f3cbeb69aa8271d5221
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Raju-Lakkaraju/net-lan743x-Fix-to-use-multiqueue-start-stop-APIs/20220907-143456
git checkout d965e2dd24f617d68ded6f3cbeb69aa8271d5221
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=sparc SHELL=/bin/bash drivers/net/ethernet/microchip/
If you fix the issue, kindly add following tag where applicable
Reported-by: kernel test robot <[email protected]>
sparse warnings: (new ones prefixed by >>)
>> drivers/net/ethernet/microchip/lan743x_main.c:2600:28: sparse: sparse: restricted __le32 degrades to integer
drivers/net/ethernet/microchip/lan743x_main.c:2601:28: sparse: sparse: restricted __le32 degrades to integer
drivers/net/ethernet/microchip/lan743x_main.c:2602:29: sparse: sparse: restricted __le32 degrades to integer
vim +2600 drivers/net/ethernet/microchip/lan743x_main.c
2544
2545 static int lan743x_rx_process_buffer(struct lan743x_rx *rx)
2546 {
2547 int current_head_index = le32_to_cpu(*rx->head_cpu_ptr);
2548 struct lan743x_rx_descriptor *descriptor, *desc_ext;
2549 struct net_device *netdev = rx->adapter->netdev;
2550 int result = RX_PROCESS_RESULT_NOTHING_TO_DO;
2551 struct lan743x_rx_buffer_info *buffer_info;
2552 int frame_length, buffer_length;
2553 bool is_ice, is_tce, is_icsm;
2554 int extension_index = -1;
2555 bool is_last, is_first;
2556 struct sk_buff *skb;
2557
2558 if (current_head_index < 0 || current_head_index >= rx->ring_size)
2559 goto done;
2560
2561 if (rx->last_head < 0 || rx->last_head >= rx->ring_size)
2562 goto done;
2563
2564 if (rx->last_head == current_head_index)
2565 goto done;
2566
2567 descriptor = &rx->ring_cpu_ptr[rx->last_head];
2568 if (le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_OWN_)
2569 goto done;
2570 buffer_info = &rx->buffer_info[rx->last_head];
2571
2572 is_last = le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_LS_;
2573 is_first = le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_FS_;
2574
2575 if (is_last && le32_to_cpu(descriptor->data0) & RX_DESC_DATA0_EXT_) {
2576 /* extension is expected to follow */
2577 int index = lan743x_rx_next_index(rx, rx->last_head);
2578
2579 if (index == current_head_index)
2580 /* extension not yet available */
2581 goto done;
2582 desc_ext = &rx->ring_cpu_ptr[index];
2583 if (le32_to_cpu(desc_ext->data0) & RX_DESC_DATA0_OWN_)
2584 /* extension not yet available */
2585 goto done;
2586 if (!(le32_to_cpu(desc_ext->data0) & RX_DESC_DATA0_EXT_))
2587 goto move_forward;
2588 extension_index = index;
2589 }
2590
2591 /* Only the last buffer in a multi-buffer frame contains the total frame
2592 * length. The chip occasionally sends more buffers than strictly
2593 * required to reach the total frame length.
2594 * Handle this by adding all buffers to the skb in their entirety.
2595 * Once the real frame length is known, trim the skb.
2596 */
2597 frame_length =
2598 RX_DESC_DATA0_FRAME_LENGTH_GET_(le32_to_cpu(descriptor->data0));
2599 buffer_length = buffer_info->buffer_length;
> 2600 is_ice = descriptor->data1 & RX_DESC_DATA1_STATUS_ICE_;
2601 is_tce = descriptor->data1 & RX_DESC_DATA1_STATUS_TCE_;
2602 is_icsm = descriptor->data1 & RX_DESC_DATA1_STATUS_ICSM_;
2603
2604 netdev_dbg(netdev, "%s%schunk: %d/%d",
2605 is_first ? "first " : " ",
2606 is_last ? "last " : " ",
2607 frame_length, buffer_length);
2608
2609 /* save existing skb, allocate new skb and map to dma */
2610 skb = buffer_info->skb;
2611 if (lan743x_rx_init_ring_element(rx, rx->last_head,
2612 GFP_ATOMIC | GFP_DMA)) {
2613 /* failed to allocate next skb.
2614 * Memory is very low.
2615 * Drop this packet and reuse buffer.
2616 */
2617 lan743x_rx_reuse_ring_element(rx, rx->last_head);
2618 /* drop packet that was being assembled */
2619 dev_kfree_skb_irq(rx->skb_head);
2620 rx->skb_head = NULL;
2621 goto process_extension;
2622 }
2623
2624 /* add buffers to skb via skb->frag_list */
2625 if (is_first) {
2626 skb_reserve(skb, RX_HEAD_PADDING);
2627 skb_put(skb, buffer_length - RX_HEAD_PADDING);
2628 if (rx->skb_head)
2629 dev_kfree_skb_irq(rx->skb_head);
2630 rx->skb_head = skb;
2631 } else if (rx->skb_head) {
2632 skb_put(skb, buffer_length);
2633 if (skb_shinfo(rx->skb_head)->frag_list)
2634 rx->skb_tail->next = skb;
2635 else
2636 skb_shinfo(rx->skb_head)->frag_list = skb;
2637 rx->skb_tail = skb;
2638 rx->skb_head->len += skb->len;
2639 rx->skb_head->data_len += skb->len;
2640 rx->skb_head->truesize += skb->truesize;
2641 } else {
2642 /* packet to assemble has already been dropped because one or
2643 * more of its buffers could not be allocated
2644 */
2645 netdev_dbg(netdev, "drop buffer intended for dropped packet");
2646 dev_kfree_skb_irq(skb);
2647 }
2648
2649 process_extension:
2650 if (extension_index >= 0) {
2651 u32 ts_sec;
2652 u32 ts_nsec;
2653
2654 ts_sec = le32_to_cpu(desc_ext->data1);
2655 ts_nsec = (le32_to_cpu(desc_ext->data2) &
2656 RX_DESC_DATA2_TS_NS_MASK_);
2657 if (rx->skb_head)
2658 skb_hwtstamps(rx->skb_head)->hwtstamp =
2659 ktime_set(ts_sec, ts_nsec);
2660 lan743x_rx_reuse_ring_element(rx, extension_index);
2661 rx->last_head = extension_index;
2662 netdev_dbg(netdev, "process extension");
2663 }
2664
2665 if (is_last && rx->skb_head)
2666 rx->skb_head = lan743x_rx_trim_skb(rx->skb_head, frame_length);
2667
2668 if (is_last && rx->skb_head) {
2669 rx->skb_head->protocol = eth_type_trans(rx->skb_head,
2670 rx->adapter->netdev);
2671 if (rx->adapter->netdev->features & NETIF_F_RXCSUM) {
2672 if (!is_ice && !is_tce && !is_icsm)
2673 skb->ip_summed = CHECKSUM_UNNECESSARY;
2674 }
2675 netdev_dbg(netdev, "sending %d byte frame to OS",
2676 rx->skb_head->len);
2677 napi_gro_receive(&rx->napi, rx->skb_head);
2678 rx->skb_head = NULL;
2679 }
2680
2681 move_forward:
2682 /* push tail and head forward */
2683 rx->last_tail = rx->last_head;
2684 rx->last_head = lan743x_rx_next_index(rx, rx->last_head);
2685 result = RX_PROCESS_RESULT_BUFFER_RECEIVED;
2686 done:
2687 return result;
2688 }
2689
--
0-DAY CI Kernel Test Service
https://01.org/lkp