lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <1523739304-25390-1-git-send-email-rafalo@cadence.com> Date: Sat, 14 Apr 2018 21:55:04 +0100 From: Rafal Ozieblo <rafalo@...ence.com> To: Nicolas Ferre <nicolas.ferre@...rochip.com>, <netdev@...r.kernel.org>, <linux-kernel@...r.kernel.org> CC: Rafal Ozieblo <rafalo@...ence.com> Subject: [PATCH 3/3] net: macb: Receive Side Coalescing (RSC) feature added. This is basically the same as Large Receive Offload (LRO) in Linux framework. Signed-off-by: Rafal Ozieblo <rafalo@...ence.com> --- drivers/net/ethernet/cadence/macb.h | 6 +++ drivers/net/ethernet/cadence/macb_main.c | 70 +++++++++++++++++++++++++++++++- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index a2cb805..9ebdde7 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -83,6 +83,7 @@ #define GEM_USRIO 0x000c /* User IO */ #define GEM_DMACFG 0x0010 /* DMA Configuration */ #define GEM_JML 0x0048 /* Jumbo Max Length */ +#define GEM_RSC 0x0058 /* RSC Control */ #define GEM_HRB 0x0080 /* Hash Bottom */ #define GEM_HRT 0x0084 /* Hash Top */ #define GEM_SA1B 0x0088 /* Specific1 Bottom */ @@ -318,6 +319,11 @@ #define GEM_ADDR64_OFFSET 30 /* Address bus width - 64b or 32b */ #define GEM_ADDR64_SIZE 1 +/* Bitfields in RSC control */ +#define GEM_RSCCTRL_OFFSET 1 /* RSC control */ +#define GEM_RSCCTRL_SIZE 15 +#define GEM_CLRMSK_OFFSET 16 /* RSC clear mask */ +#define GEM_CLRMSK_SIZE 1 /* Bitfields in NSR */ #define MACB_NSR_LINK_OFFSET 0 /* pcs_link_state */ diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 27c406c..92bdcf1 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2377,6 +2377,8 @@ static int macb_open(struct net_device *dev) if (!(bp->dev->hw_features & NETIF_F_LRO)) bufsz += NET_IP_ALIGN; + else + bufsz = 0xFF * 64; // For RSC Buffer Sizes must be set to 16K. /* RX buffers initialization */ macb_init_rx_buffer_size(bp, bufsz); @@ -2801,6 +2803,62 @@ static int macb_get_ts_info(struct net_device *netdev, return ethtool_op_get_ts_info(netdev, info); } +static void gem_enable_hdr_data_split(struct macb *bp, bool enable) +{ + u32 dmacfg; + + dmacfg = gem_readl(bp, DMACFG); + if (enable) + dmacfg |= GEM_BIT(HDRS); + else + dmacfg &= ~GEM_BIT(HDRS); + gem_writel(bp, DMACFG, dmacfg); +} + +static void gem_update_rsc_state(struct macb *bp, netdev_features_t feature) +{ + u32 rsc_control, rsc_control_new, queue, rsc; + bool enable, jumbo, any_enabled = false; + struct ethtool_rx_fs_item *item; + unsigned long flags; + u32 ncfgr; + + enable = (!!(feature & NETIF_F_NTUPLE) && !!(feature & NETIF_F_LRO)); + rsc = gem_readl(bp, RSC); + rsc_control = GEM_BFEXT(RSCCTRL, rsc); + rsc_control_new = 0; + if (enable) { + list_for_each_entry(item, &bp->rx_fs_list.list, list) { + queue = item->fs.ring_cookie; + rsc_control_new |= (1 << (queue - 1)); + any_enabled = true; + netdev_dbg(bp->dev, "RSC %sabled for queue %u\n", + enable ? "en" : "dis", queue); + } + } + if (rsc_control_new != rsc_control) { + rsc = GEM_BFINS(RSCCTRL, rsc_control_new, rsc); + gem_writel(bp, RSC, rsc); + } + if (bp->caps & MACB_CAPS_JUMBO) { + /* Don't enable jumbo mode for RSC: + * disable unless not RSC and large MTU + */ + ncfgr = gem_readl(bp, NCFGR); + enable = !any_enabled; + jumbo = !!MACB_BFEXT(JFRAME, ncfgr); + /* and don't touch if already in the state we want */ + if ((jumbo && !enable) || (!jumbo && enable)) { + ncfgr = MACB_BFINS(JFRAME, enable, ncfgr); + spin_lock_irqsave(&bp->lock, flags); + gem_writel(bp, NCFGR, ncfgr); + spin_unlock_irqrestore(&bp->lock, flags); + } + } + /* Need to enable header-data splitting also */ + gem_enable_hdr_data_split(bp, any_enabled); +} + static void gem_enable_flow_filters(struct macb *bp, bool enable) { struct ethtool_rx_fs_item *item; @@ -2969,6 +3027,8 @@ static int gem_add_flow_filter(struct net_device *netdev, if (netdev->features & NETIF_F_NTUPLE) gem_enable_flow_filters(bp, 1); + /* enable RSC if LRO & NTUPLE on */ + gem_update_rsc_state(bp, netdev->features); spin_unlock_irqrestore(&bp->rx_fs_lock, flags); return 0; @@ -3009,6 +3069,7 @@ static int gem_del_flow_filter(struct net_device *netdev, return 0; } } + gem_update_rsc_state(bp, netdev->features); spin_unlock_irqrestore(&bp->rx_fs_lock, flags); return -EINVAL; @@ -3191,7 +3252,12 @@ static int macb_set_features(struct net_device *netdev, bool turn_on = features & NETIF_F_NTUPLE; gem_enable_flow_filters(bp, turn_on); + gem_update_rsc_state(bp, features); } + + /* LRO (Large Receive Offload) aka RSC (Receive Side Coalescing) */ + if ((changed & NETIF_F_LRO) && macb_is_gem(bp)) + gem_update_rsc_state(bp, features); return 0; } @@ -3449,8 +3515,10 @@ static int macb_init(struct platform_device *pdev) dev->hw_features |= MACB_NETIF_LSO; /* Check RSC capability */ - if (GEM_BFEXT(PBUF_RSC, gem_readl(bp, DCFG6))) + if (GEM_BFEXT(PBUF_RSC, gem_readl(bp, DCFG6))) { dev->hw_features |= NETIF_F_LRO; + gem_writel(bp, RSC, GEM_BIT(CLRMSK)); + } /* Checksum offload is only available on gem with packet buffer */ if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE)) -- 2.4.5
Powered by blists - more mailing lists