Skip to content

Commit

Permalink
Revert "net: bcmgenet: always enable status blocks"
Browse files Browse the repository at this point in the history
This reverts commit 9a9ba2a.

See: #3850

Signed-off-by: Phil Elwell <[email protected]>
  • Loading branch information
pelwell committed Sep 24, 2020
1 parent 017d4f3 commit 4b70b35
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 38 deletions.
132 changes: 95 additions & 37 deletions drivers/net/ethernet/broadcom/genet/bcmgenet.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ static inline void dmadesc_set_length_status(struct bcmgenet_priv *priv,
bcmgenet_writel(value, d + DMA_DESC_LENGTH_STATUS);
}

static inline u32 dmadesc_get_length_status(struct bcmgenet_priv *priv,
void __iomem *d)
{
return bcmgenet_readl(d + DMA_DESC_LENGTH_STATUS);
}

static inline void dmadesc_set_addr(struct bcmgenet_priv *priv,
void __iomem *d,
dma_addr_t addr)
Expand Down Expand Up @@ -796,6 +802,61 @@ static int bcmgenet_set_link_ksettings(struct net_device *dev,
return phy_ethtool_ksettings_set(dev->phydev, cmd);
}

static void bcmgenet_set_rx_csum(struct net_device *dev,
netdev_features_t wanted)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
u32 rbuf_chk_ctrl;
bool rx_csum_en;

rx_csum_en = !!(wanted & NETIF_F_RXCSUM);

rbuf_chk_ctrl = bcmgenet_rbuf_readl(priv, RBUF_CHK_CTRL);

/* enable rx checksumming */
if (rx_csum_en)
rbuf_chk_ctrl |= RBUF_RXCHK_EN | RBUF_L3_PARSE_DIS;
else
rbuf_chk_ctrl &= ~RBUF_RXCHK_EN;
priv->desc_rxchk_en = rx_csum_en;

/* If UniMAC forwards CRC, we need to skip over it to get
* a valid CHK bit to be set in the per-packet status word
*/
if (rx_csum_en && priv->crc_fwd_en)
rbuf_chk_ctrl |= RBUF_SKIP_FCS;
else
rbuf_chk_ctrl &= ~RBUF_SKIP_FCS;

bcmgenet_rbuf_writel(priv, rbuf_chk_ctrl, RBUF_CHK_CTRL);
}

static void bcmgenet_set_tx_csum(struct net_device *dev,
netdev_features_t wanted)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
bool desc_64b_en;
u32 tbuf_ctrl, rbuf_ctrl;

tbuf_ctrl = bcmgenet_tbuf_ctrl_get(priv);
rbuf_ctrl = bcmgenet_rbuf_readl(priv, RBUF_CTRL);

desc_64b_en = !!(wanted & NETIF_F_HW_CSUM);

/* enable 64 bytes descriptor in both directions (RBUF and TBUF) */
if (desc_64b_en) {
tbuf_ctrl |= RBUF_64B_EN;
rbuf_ctrl |= RBUF_64B_EN;
} else {
tbuf_ctrl &= ~RBUF_64B_EN;
rbuf_ctrl &= ~RBUF_64B_EN;
}
priv->desc_64b_en = desc_64b_en;

bcmgenet_tbuf_ctrl_set(priv, tbuf_ctrl);
bcmgenet_rbuf_writel(priv, rbuf_ctrl, RBUF_CTRL);
}

static int bcmgenet_set_features(struct net_device *dev,
netdev_features_t features)
{
Expand All @@ -811,6 +872,9 @@ static int bcmgenet_set_features(struct net_device *dev,
reg = bcmgenet_umac_readl(priv, UMAC_CMD);
priv->crc_fwd_en = !!(reg & CMD_CRC_FWD);

bcmgenet_set_tx_csum(dev, features);
bcmgenet_set_rx_csum(dev, features);

clk_disable_unprepare(priv->clk);

return ret;
Expand Down Expand Up @@ -1929,8 +1993,8 @@ static void bcmgenet_tx_reclaim_all(struct net_device *dev)
/* Reallocate the SKB to put enough headroom in front of it and insert
* the transmit checksum offsets in the descriptors
*/
static struct sk_buff *bcmgenet_add_tsb(struct net_device *dev,
struct sk_buff *skb)
static struct sk_buff *bcmgenet_put_tx_csum(struct net_device *dev,
struct sk_buff *skb)
{
struct bcmgenet_priv *priv = netdev_priv(dev);
struct status_64 *status = NULL;
Expand Down Expand Up @@ -2039,11 +2103,13 @@ static netdev_tx_t bcmgenet_xmit(struct sk_buff *skb, struct net_device *dev)
*/
GENET_CB(skb)->bytes_sent = skb->len;

/* add the Transmit Status Block */
skb = bcmgenet_add_tsb(dev, skb);
if (!skb) {
ret = NETDEV_TX_OK;
goto out;
/* set the SKB transmit checksum */
if (priv->desc_64b_en) {
skb = bcmgenet_put_tx_csum(dev, skb);
if (!skb) {
ret = NETDEV_TX_OK;
goto out;
}
}

for (i = 0; i <= nr_frags; i++) {
Expand Down Expand Up @@ -2226,9 +2292,6 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,

while ((rxpktprocessed < rxpkttoprocess) &&
(rxpktprocessed < budget)) {
struct status_64 *status;
__be16 rx_csum;

cb = &priv->rx_cbs[ring->read_ptr];
skb = bcmgenet_rx_refill(priv, cb);

Expand All @@ -2237,12 +2300,20 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
goto next;
}

status = (struct status_64 *)skb->data;
dma_length_status = status->length_status;
if (dev->features & NETIF_F_RXCSUM) {
if (!priv->desc_64b_en) {
dma_length_status =
dmadesc_get_length_status(priv, cb->bd_addr);
} else {
struct status_64 *status;
__be16 rx_csum;

status = (struct status_64 *)skb->data;
dma_length_status = status->length_status;
rx_csum = (__force __be16)(status->rx_csum & 0xffff);
skb->csum = (__force __wsum)ntohs(rx_csum);
skb->ip_summed = CHECKSUM_COMPLETE;
if (priv->desc_rxchk_en) {
skb->csum = (__force __wsum)ntohs(rx_csum);
skb->ip_summed = CHECKSUM_COMPLETE;
}
}

/* DMA flags and length are still valid no matter how
Expand Down Expand Up @@ -2286,10 +2357,14 @@ static unsigned int bcmgenet_desc_rx(struct bcmgenet_rx_ring *ring,
} /* error packet */

skb_put(skb, len);
if (priv->desc_64b_en) {
skb_pull(skb, 64);
len -= 64;
}

/* remove RSB and hardware 2bytes added for IP alignment */
skb_pull(skb, 66);
len -= 66;
/* remove hardware 2bytes added for IP alignment */
skb_pull(skb, 2);
len -= 2;

if (priv->crc_fwd_en) {
skb_trim(skb, len - ETH_FCS_LEN);
Expand Down Expand Up @@ -2485,28 +2560,11 @@ static void init_umac(struct bcmgenet_priv *priv)

bcmgenet_umac_writel(priv, ENET_MAX_MTU_SIZE, UMAC_MAX_FRAME_LEN);

/* init tx registers, enable TSB */
reg = bcmgenet_tbuf_ctrl_get(priv);
reg |= TBUF_64B_EN;
bcmgenet_tbuf_ctrl_set(priv, reg);

/* init rx registers, enable ip header optimization and RSB */
/* init rx registers, enable ip header optimization */
reg = bcmgenet_rbuf_readl(priv, RBUF_CTRL);
reg |= RBUF_ALIGN_2B | RBUF_64B_EN;
reg |= RBUF_ALIGN_2B;
bcmgenet_rbuf_writel(priv, reg, RBUF_CTRL);

/* enable rx checksumming */
reg = bcmgenet_rbuf_readl(priv, RBUF_CHK_CTRL);
reg |= RBUF_RXCHK_EN | RBUF_L3_PARSE_DIS;
/* If UniMAC forwards CRC, we need to skip over it to get
* a valid CHK bit to be set in the per-packet status word
*/
if (priv->crc_fwd_en)
reg |= RBUF_SKIP_FCS;
else
reg &= ~RBUF_SKIP_FCS;
bcmgenet_rbuf_writel(priv, reg, RBUF_CHK_CTRL);

if (!GENET_IS_V1(priv) && !GENET_IS_V2(priv))
bcmgenet_rbuf_writel(priv, 1, RBUF_TBUF_SIZE_CTRL);

Expand Down
3 changes: 2 additions & 1 deletion drivers/net/ethernet/broadcom/genet/bcmgenet.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,6 @@ struct bcmgenet_mib_counters {
#define RBUF_FLTR_LEN_SHIFT 8

#define TBUF_CTRL 0x00
#define TBUF_64B_EN (1 << 0)
#define TBUF_BP_MC 0x0C
#define TBUF_ENERGY_CTRL 0x14
#define TBUF_EEE_EN (1 << 0)
Expand Down Expand Up @@ -681,6 +680,8 @@ struct bcmgenet_priv {
unsigned int irq0_stat;

/* HW descriptors/checksum variables */
bool desc_64b_en;
bool desc_rxchk_en;
bool crc_fwd_en;

u32 dma_max_burst_length;
Expand Down

0 comments on commit 4b70b35

Please sign in to comment.