1010#include <linux/acpi.h>
1111#include <linux/kernel.h>
1212#include <linux/module.h>
13+ #include <linux/of.h>
1314#include <linux/sched.h>
1415#include <linux/types.h>
1516#include <linux/fcntl.h>
5152
5253#define SKB_ALIGNMENT 32
5354
55+ /* Test only, see the commit message */
56+ static bool experimental_jumbo ;
57+ module_param (experimental_jumbo , bool , 0444 );
58+ MODULE_PARM_DESC (experimental_jumbo ,
59+ "9000 byte MTU, costs the status blocks and checksum offload" );
60+
5461/* Tx/Rx DMA register offset, skip 256 descriptors */
5562#define WORDS_PER_BD (p ) (p->hw_params->words_per_bd)
5663#define DMA_DESC_SIZE (WORDS_PER_BD(priv) * sizeof(u32))
@@ -2150,11 +2157,13 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
21502157 */
21512158 GENET_CB (skb )-> bytes_sent = skb -> len ;
21522159
2153- /* add the Transmit Status Block */
2154- skb = bcmgenet_add_tsb (dev , skb , ring );
2155- if (!skb ) {
2156- ret = NETDEV_TX_OK ;
2157- goto out ;
2160+ /* No TSB, probe cleared the checksum offloads */
2161+ if (!experimental_jumbo ) {
2162+ skb = bcmgenet_add_tsb (dev , skb , ring );
2163+ if (!skb ) {
2164+ ret = NETDEV_TX_OK ;
2165+ goto out ;
2166+ }
21582167 }
21592168
21602169 for (i = 0 ; i <= nr_frags ; i ++ ) {
@@ -2209,7 +2218,8 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
22092218
22102219 GENET_CB (skb )-> last_cb = tx_cb_ptr ;
22112220
2212- bcmgenet_hide_tsb (skb );
2221+ if (!experimental_jumbo )
2222+ bcmgenet_hide_tsb (skb );
22132223 skb_tx_timestamp (skb );
22142224
22152225 /* Decrement total BD count and advance our write pointer */
@@ -2339,20 +2349,25 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
23392349 __be16 rx_csum ;
23402350
23412351 cb = & priv -> rx_cbs [ring -> read_ptr ];
2352+ if (experimental_jumbo )
2353+ dma_length_status = bcmgenet_readl (cb -> bd_addr +
2354+ DMA_DESC_LENGTH_STATUS );
23422355 skb = bcmgenet_rx_refill (priv , cb );
23432356
23442357 if (unlikely (!skb )) {
23452358 BCMGENET_STATS64_INC (stats , dropped );
23462359 goto next ;
23472360 }
23482361
2349- status = (struct status_64 * )skb -> data ;
2350- dma_length_status = status -> length_status ;
2351- if (dev -> features & NETIF_F_RXCSUM ) {
2352- rx_csum = (__force __be16 )(status -> rx_csum & 0xffff );
2353- if (rx_csum ) {
2354- skb -> csum = (__force __wsum )ntohs (rx_csum );
2355- skb -> ip_summed = CHECKSUM_COMPLETE ;
2362+ if (!experimental_jumbo ) {
2363+ status = (struct status_64 * )skb -> data ;
2364+ dma_length_status = status -> length_status ;
2365+ if (dev -> features & NETIF_F_RXCSUM ) {
2366+ rx_csum = (__force __be16 )(status -> rx_csum & 0xffff );
2367+ if (rx_csum ) {
2368+ skb -> csum = (__force __wsum )ntohs (rx_csum );
2369+ skb -> ip_summed = CHECKSUM_COMPLETE ;
2370+ }
23562371 }
23572372 }
23582373
@@ -2367,7 +2382,10 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
23672382 __func__ , p_index , ring -> c_index ,
23682383 ring -> read_ptr , dma_length_status );
23692384
2370- if (unlikely (len > priv -> rx_buf_len )) {
2385+ if (unlikely (len > priv -> rx_buf_len ||
2386+ len < (experimental_jumbo ? ENET_RBUF_ALIGN :
2387+ ENET_RX_OFFSET ) + ETH_HLEN +
2388+ (priv -> crc_fwd_en ? ETH_FCS_LEN : 0 ))) {
23712389 netif_err (priv , rx_status , dev , "oversized packet\n" );
23722390 BCMGENET_STATS64_INC (stats , length_errors );
23732391 dev_kfree_skb_any (skb );
@@ -2412,9 +2430,14 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
24122430
24132431 skb_put (skb , len );
24142432
2415- /* remove RSB and hardware 2bytes added for IP alignment */
2416- skb_pull (skb , ENET_RX_OFFSET );
2417- len -= ENET_RX_OFFSET ;
2433+ /* Remove the alignment bytes, and the RSB if there is one */
2434+ if (experimental_jumbo ) {
2435+ skb_pull (skb , ENET_RBUF_ALIGN );
2436+ len -= ENET_RBUF_ALIGN ;
2437+ } else {
2438+ skb_pull (skb , ENET_RX_OFFSET );
2439+ len -= ENET_RX_OFFSET ;
2440+ }
24182441
24192442 if (priv -> crc_fwd_en ) {
24202443 skb_trim (skb , len - ETH_FCS_LEN );
@@ -2612,6 +2635,11 @@ static unsigned int bcmgenet_pkt_rdy_thld(unsigned int mtu)
26122635/* A buffer has to hold everything the threshold lets the hardware deliver */
26132636static unsigned int bcmgenet_rx_buf_len (unsigned int mtu )
26142637{
2638+ if (experimental_jumbo )
2639+ return max_t (unsigned int , ENET_THLD_DEFAULT * ENET_THLD_UNIT ,
2640+ round_up (ENET_MAX_FRAME_LEN (mtu ) + ENET_RBUF_ALIGN ,
2641+ ENET_THLD_BURST ));
2642+
26152643 return ENET_RSB_LEN + bcmgenet_pkt_rdy_thld (mtu ) * ENET_THLD_UNIT ;
26162644}
26172645
@@ -2652,17 +2680,28 @@ static void init_umac(struct bcmgenet_priv *priv)
26522680
26532681 /* init tx registers, enable TSB */
26542682 reg = bcmgenet_tbuf_ctrl_get (priv );
2655- reg |= TBUF_64B_EN ;
2683+ if (experimental_jumbo )
2684+ reg &= ~TBUF_64B_EN ;
2685+ else
2686+ reg |= TBUF_64B_EN ;
26562687 bcmgenet_tbuf_ctrl_set (priv , reg );
26572688
26582689 /* init rx registers, enable ip header optimization and RSB */
26592690 reg = bcmgenet_rbuf_readl (priv , RBUF_CTRL );
2660- reg |= RBUF_ALIGN_2B | RBUF_64B_EN ;
2691+ reg |= RBUF_ALIGN_2B ;
2692+ if (experimental_jumbo )
2693+ reg &= ~RBUF_64B_EN ;
2694+ else
2695+ reg |= RBUF_64B_EN ;
26612696 bcmgenet_rbuf_writel (priv , reg , RBUF_CTRL );
26622697
26632698 /* enable rx checksumming */
26642699 reg = bcmgenet_rbuf_readl (priv , RBUF_CHK_CTRL );
2665- reg |= RBUF_RXCHK_EN | RBUF_L3_PARSE_DIS ;
2700+ reg |= RBUF_L3_PARSE_DIS ;
2701+ if (experimental_jumbo )
2702+ reg &= ~RBUF_RXCHK_EN ;
2703+ else
2704+ reg |= RBUF_RXCHK_EN ;
26662705 /* If UniMAC forwards CRC, we need to skip over it to get
26672706 * a valid CHK bit to be set in the per-packet status word
26682707 */
@@ -4132,6 +4171,18 @@ static int bcmgenet_probe(struct platform_device *pdev)
41324171
41334172 bcmgenet_set_hw_params (priv );
41344173
4174+ if (experimental_jumbo ) {
4175+ if (!of_device_is_compatible (pdev -> dev .of_node ,
4176+ "brcm,bcm2711-genet-v5" )) {
4177+ err = - EOPNOTSUPP ;
4178+ goto err_clk_disable ;
4179+ }
4180+ dev -> features &= ~(NETIF_F_CSUM_MASK | NETIF_F_RXCSUM );
4181+ dev -> hw_features &= ~(NETIF_F_CSUM_MASK | NETIF_F_RXCSUM );
4182+ dev -> vlan_features &= ~(NETIF_F_CSUM_MASK | NETIF_F_RXCSUM );
4183+ dev_warn (& pdev -> dev , "experimental jumbo mode enabled\n" );
4184+ }
4185+
41354186 err = - EIO ;
41364187 if (bcmgenet_has_40bits (priv ))
41374188 err = dma_set_mask_and_coherent (& pdev -> dev , DMA_BIT_MASK (40 ));
@@ -4147,7 +4198,7 @@ static int bcmgenet_probe(struct platform_device *pdev)
41474198 /* v1 cannot program the thresholds, so it stays at the default MTU */
41484199 priv -> rx_buf_len = bcmgenet_rx_buf_len (dev -> mtu );
41494200 if (!GENET_IS_V1 (priv ))
4150- dev -> max_mtu = ENET_MAX_MTU ;
4201+ dev -> max_mtu = experimental_jumbo ? 9000 : ENET_MAX_MTU ;
41514202 INIT_WORK (& priv -> bcmgenet_irq_work , bcmgenet_irq_task );
41524203
41534204 priv -> clk_wol = devm_clk_get_optional (& priv -> pdev -> dev , "enet-wol" );
@@ -4193,7 +4244,8 @@ static int bcmgenet_probe(struct platform_device *pdev)
41934244 goto err_clk_disable ;
41944245
41954246 /* setup number of real queues + 1 */
4196- netif_set_real_num_tx_queues (priv -> dev , priv -> hw_params -> tx_queues + 1 );
4247+ netif_set_real_num_tx_queues (priv -> dev , experimental_jumbo ? 1 :
4248+ priv -> hw_params -> tx_queues + 1 );
41974249 netif_set_real_num_rx_queues (priv -> dev , priv -> hw_params -> rx_queues + 1 );
41984250
41994251 /* Set default coalescing parameters */
0 commit comments