Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Linux/drivers/net/ethernet/broadcom/bnge/   (Open Source Betriebssystem Version 6.17.9©)  Datei vom 24.10.2025 mit Größe 6 kB image not shown  

Quelle  bnge_netdev.c   Sprache: C

 
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2025 Broadcom.

#include <asm/byteorder.h>
#include <linux/dma-mapping.h>
#include <linux/dmapool.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if.h>
#include <net/ip.h>
#include <linux/skbuff.h>

#include "bnge.h"
#include "bnge_hwrm_lib.h"
#include "bnge_ethtool.h"

static netdev_tx_t bnge_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
 dev_kfree_skb_any(skb);

 return NETDEV_TX_OK;
}

static int bnge_open(struct net_device *dev)
{
 return 0;
}

static int bnge_close(struct net_device *dev)
{
 return 0;
}

static const struct net_device_ops bnge_netdev_ops = {
 .ndo_open  = bnge_open,
 .ndo_stop  = bnge_close,
 .ndo_start_xmit  = bnge_start_xmit,
};

static void bnge_init_mac_addr(struct bnge_dev *bd)
{
 eth_hw_addr_set(bd->netdev, bd->pf.mac_addr);
}

static void bnge_set_tpa_flags(struct bnge_dev *bd)
{
 struct bnge_net *bn = netdev_priv(bd->netdev);

 bn->priv_flags &= ~BNGE_NET_EN_TPA;

 if (bd->netdev->features & NETIF_F_LRO)
  bn->priv_flags |= BNGE_NET_EN_LRO;
 else if (bd->netdev->features & NETIF_F_GRO_HW)
  bn->priv_flags |= BNGE_NET_EN_GRO;
}

static void bnge_init_l2_fltr_tbl(struct bnge_net *bn)
{
 int i;

 for (i = 0; i < BNGE_L2_FLTR_HASH_SIZE; i++)
  INIT_HLIST_HEAD(&bn->l2_fltr_hash_tbl[i]);
 get_random_bytes(&bn->hash_seed, sizeof(bn->hash_seed));
}

void bnge_set_ring_params(struct bnge_dev *bd)
{
 struct bnge_net *bn = netdev_priv(bd->netdev);
 u32 ring_size, rx_size, rx_space, max_rx_cmpl;
 u32 agg_factor = 0, agg_ring_size = 0;

 /* 8 for CRC and VLAN */
 rx_size = SKB_DATA_ALIGN(bn->netdev->mtu + ETH_HLEN + NET_IP_ALIGN + 8);

 rx_space = rx_size + ALIGN(NET_SKB_PAD, 8) +
  SKB_DATA_ALIGN(sizeof(struct skb_shared_info));

 bn->rx_copy_thresh = BNGE_RX_COPY_THRESH;
 ring_size = bn->rx_ring_size;
 bn->rx_agg_ring_size = 0;
 bn->rx_agg_nr_pages = 0;

 if (bn->priv_flags & BNGE_NET_EN_TPA)
  agg_factor = min_t(u32, 4, 65536 / BNGE_RX_PAGE_SIZE);

 bn->priv_flags &= ~BNGE_NET_EN_JUMBO;
 if (rx_space > PAGE_SIZE) {
  u32 jumbo_factor;

  bn->priv_flags |= BNGE_NET_EN_JUMBO;
  jumbo_factor = PAGE_ALIGN(bn->netdev->mtu - 40) >> PAGE_SHIFT;
  if (jumbo_factor > agg_factor)
   agg_factor = jumbo_factor;
 }
 if (agg_factor) {
  if (ring_size > BNGE_MAX_RX_DESC_CNT_JUM_ENA) {
   ring_size = BNGE_MAX_RX_DESC_CNT_JUM_ENA;
   netdev_warn(bn->netdev, "RX ring size reduced from %d to %d due to jumbo ring\n",
        bn->rx_ring_size, ring_size);
   bn->rx_ring_size = ring_size;
  }
  agg_ring_size = ring_size * agg_factor;

  bn->rx_agg_nr_pages = bnge_adjust_pow_two(agg_ring_size,
         RX_DESC_CNT);
  if (bn->rx_agg_nr_pages > MAX_RX_AGG_PAGES) {
   u32 tmp = agg_ring_size;

   bn->rx_agg_nr_pages = MAX_RX_AGG_PAGES;
   agg_ring_size = MAX_RX_AGG_PAGES * RX_DESC_CNT - 1;
   netdev_warn(bn->netdev, "RX agg ring size %d reduced to %d.\n",
        tmp, agg_ring_size);
  }
  bn->rx_agg_ring_size = agg_ring_size;
  bn->rx_agg_ring_mask = (bn->rx_agg_nr_pages * RX_DESC_CNT) - 1;

  rx_size = SKB_DATA_ALIGN(BNGE_RX_COPY_THRESH + NET_IP_ALIGN);
  rx_space = rx_size + NET_SKB_PAD +
   SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
 }

 bn->rx_buf_use_size = rx_size;
 bn->rx_buf_size = rx_space;

 bn->rx_nr_pages = bnge_adjust_pow_two(ring_size, RX_DESC_CNT);
 bn->rx_ring_mask = (bn->rx_nr_pages * RX_DESC_CNT) - 1;

 ring_size = bn->tx_ring_size;
 bn->tx_nr_pages = bnge_adjust_pow_two(ring_size, TX_DESC_CNT);
 bn->tx_ring_mask = (bn->tx_nr_pages * TX_DESC_CNT) - 1;

 max_rx_cmpl = bn->rx_ring_size;

 if (bn->priv_flags & BNGE_NET_EN_TPA)
  max_rx_cmpl += bd->max_tpa_v2;
 ring_size = max_rx_cmpl * 2 + agg_ring_size + bn->tx_ring_size;
 bn->cp_ring_size = ring_size;

 bn->cp_nr_pages = bnge_adjust_pow_two(ring_size, CP_DESC_CNT);
 if (bn->cp_nr_pages > MAX_CP_PAGES) {
  bn->cp_nr_pages = MAX_CP_PAGES;
  bn->cp_ring_size = MAX_CP_PAGES * CP_DESC_CNT - 1;
  netdev_warn(bn->netdev, "completion ring size %d reduced to %d.\n",
       ring_size, bn->cp_ring_size);
 }
 bn->cp_bit = bn->cp_nr_pages * CP_DESC_CNT;
 bn->cp_ring_mask = bn->cp_bit - 1;
}

int bnge_netdev_alloc(struct bnge_dev *bd, int max_irqs)
{
 struct net_device *netdev;
 struct bnge_net *bn;
 int rc;

 netdev = alloc_etherdev_mqs(sizeof(*bn), max_irqs * BNGE_MAX_QUEUE,
        max_irqs);
 if (!netdev)
  return -ENOMEM;

 SET_NETDEV_DEV(netdev, bd->dev);
 bd->netdev = netdev;

 netdev->netdev_ops = &bnge_netdev_ops;

 bnge_set_ethtool_ops(netdev);

 bn = netdev_priv(netdev);
 bn->netdev = netdev;
 bn->bd = bd;

 netdev->min_mtu = ETH_ZLEN;
 netdev->max_mtu = bd->max_mtu;

 netdev->hw_features = NETIF_F_IP_CSUM |
         NETIF_F_IPV6_CSUM |
         NETIF_F_SG |
         NETIF_F_TSO |
         NETIF_F_TSO6 |
         NETIF_F_GSO_UDP_TUNNEL |
         NETIF_F_GSO_GRE |
         NETIF_F_GSO_IPXIP4 |
         NETIF_F_GSO_UDP_TUNNEL_CSUM |
         NETIF_F_GSO_GRE_CSUM |
         NETIF_F_GSO_PARTIAL |
         NETIF_F_RXHASH |
         NETIF_F_RXCSUM |
         NETIF_F_GRO;

 if (bd->flags & BNGE_EN_UDP_GSO_SUPP)
  netdev->hw_features |= NETIF_F_GSO_UDP_L4;

 if (BNGE_SUPPORTS_TPA(bd))
  netdev->hw_features |= NETIF_F_LRO;

 netdev->hw_enc_features = NETIF_F_IP_CSUM |
      NETIF_F_IPV6_CSUM |
      NETIF_F_SG |
      NETIF_F_TSO |
      NETIF_F_TSO6 |
      NETIF_F_GSO_UDP_TUNNEL |
      NETIF_F_GSO_GRE |
      NETIF_F_GSO_UDP_TUNNEL_CSUM |
      NETIF_F_GSO_GRE_CSUM |
      NETIF_F_GSO_IPXIP4 |
      NETIF_F_GSO_PARTIAL;

 if (bd->flags & BNGE_EN_UDP_GSO_SUPP)
  netdev->hw_enc_features |= NETIF_F_GSO_UDP_L4;

 netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM |
           NETIF_F_GSO_GRE_CSUM;

 netdev->vlan_features = netdev->hw_features | NETIF_F_HIGHDMA;
 if (bd->fw_cap & BNGE_FW_CAP_VLAN_RX_STRIP)
  netdev->hw_features |= BNGE_HW_FEATURE_VLAN_ALL_RX;
 if (bd->fw_cap & BNGE_FW_CAP_VLAN_TX_INSERT)
  netdev->hw_features |= BNGE_HW_FEATURE_VLAN_ALL_TX;

 if (BNGE_SUPPORTS_TPA(bd))
  netdev->hw_features |= NETIF_F_GRO_HW;

 netdev->features |= netdev->hw_features | NETIF_F_HIGHDMA;

 if (netdev->features & NETIF_F_GRO_HW)
  netdev->features &= ~NETIF_F_LRO;

 netdev->priv_flags |= IFF_UNICAST_FLT;

 netif_set_tso_max_size(netdev, GSO_MAX_SIZE);
 if (bd->tso_max_segs)
  netif_set_tso_max_segs(netdev, bd->tso_max_segs);

 bn->rx_ring_size = BNGE_DEFAULT_RX_RING_SIZE;
 bn->tx_ring_size = BNGE_DEFAULT_TX_RING_SIZE;

 bnge_set_tpa_flags(bd);
 bnge_set_ring_params(bd);

 bnge_init_l2_fltr_tbl(bn);
 bnge_init_mac_addr(bd);

 rc = register_netdev(netdev);
 if (rc) {
  dev_err(bd->dev, "Register netdev failed rc: %d\n", rc);
  goto err_netdev;
 }

 return 0;

err_netdev:
 free_netdev(netdev);
 return rc;
}

void bnge_netdev_free(struct bnge_dev *bd)
{
 struct net_device *netdev = bd->netdev;

 unregister_netdev(netdev);
 free_netdev(netdev);
 bd->netdev = NULL;
}

Messung V0.5
C=99 H=93 G=95

¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.