From 40a1578d631a8ac1cf0ef797c435114107747859 Mon Sep 17 00:00:00 2001 From: Claudiu Manoil Date: Tue, 21 May 2019 19:52:55 +0300 Subject: ocelot: Dont allocate another multicast list, use __dev_mc_sync Doing kmalloc in atomic context is always an issue, more so for a list that can grow significantly. Turns out that the driver only uses the duplicated list of multicast mac addresses to keep track of what addresses to delete from h/w before committing the new list from kernel to h/w back again via set_rx_mode, every time this list gets updated by the kernel. Given that the h/w knows how to add and delete mac addresses based on the mac address value alone, __dev_mc_sync should be the much better choice of kernel API for these operations avoiding the considerable overhead of maintaining a duplicated list in the driver. Signed-off-by: Claudiu Manoil Tested-by: Alexandre Belloni Acked-by: Alexandre Belloni Signed-off-by: David S. Miller --- drivers/net/ethernet/mscc/ocelot.c | 43 +++++++------------------------------- drivers/net/ethernet/mscc/ocelot.h | 4 ---- 2 files changed, 8 insertions(+), 39 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c index d715ef4fc92f..02ad11e0b0d8 100644 --- a/drivers/net/ethernet/mscc/ocelot.c +++ b/drivers/net/ethernet/mscc/ocelot.c @@ -593,45 +593,25 @@ static int ocelot_port_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_OK; } -static void ocelot_mact_mc_reset(struct ocelot_port *port) +static int ocelot_mc_unsync(struct net_device *dev, const unsigned char *addr) { - struct ocelot *ocelot = port->ocelot; - struct netdev_hw_addr *ha, *n; + struct ocelot_port *port = netdev_priv(dev); - /* Free and forget all the MAC addresses stored in the port private mc - * list. These are mc addresses that were previously added by calling - * ocelot_mact_mc_add(). - */ - list_for_each_entry_safe(ha, n, &port->mc, list) { - ocelot_mact_forget(ocelot, ha->addr, port->pvid); - list_del(&ha->list); - kfree(ha); - } + return ocelot_mact_forget(port->ocelot, addr, port->pvid); } -static int ocelot_mact_mc_add(struct ocelot_port *port, - struct netdev_hw_addr *hw_addr) +static int ocelot_mc_sync(struct net_device *dev, const unsigned char *addr) { - struct ocelot *ocelot = port->ocelot; - struct netdev_hw_addr *ha = kzalloc(sizeof(*ha), GFP_ATOMIC); - - if (!ha) - return -ENOMEM; - - memcpy(ha, hw_addr, sizeof(*ha)); - list_add_tail(&ha->list, &port->mc); - - ocelot_mact_learn(ocelot, PGID_CPU, ha->addr, port->pvid, - ENTRYTYPE_LOCKED); + struct ocelot_port *port = netdev_priv(dev); - return 0; + return ocelot_mact_learn(port->ocelot, PGID_CPU, addr, port->pvid, + ENTRYTYPE_LOCKED); } static void ocelot_set_rx_mode(struct net_device *dev) { struct ocelot_port *port = netdev_priv(dev); struct ocelot *ocelot = port->ocelot; - struct netdev_hw_addr *ha; int i; u32 val; @@ -643,13 +623,7 @@ static void ocelot_set_rx_mode(struct net_device *dev) for (i = ocelot->num_phys_ports + 1; i < PGID_CPU; i++) ocelot_write_rix(ocelot, val, ANA_PGID_PGID, i); - /* Handle the device multicast addresses. First remove all the - * previously installed addresses and then add the latest ones to the - * mac table. - */ - ocelot_mact_mc_reset(port); - netdev_for_each_mc_addr(ha, dev) - ocelot_mact_mc_add(port, ha); + __dev_mc_sync(dev, ocelot_mc_sync, ocelot_mc_unsync); } static int ocelot_port_get_phys_port_name(struct net_device *dev, @@ -1657,7 +1631,6 @@ int ocelot_probe_port(struct ocelot *ocelot, u8 port, ocelot_port->regs = regs; ocelot_port->chip_port = port; ocelot_port->phy = phy; - INIT_LIST_HEAD(&ocelot_port->mc); ocelot->ports[port] = ocelot_port; dev->netdev_ops = &ocelot_port_netdev_ops; diff --git a/drivers/net/ethernet/mscc/ocelot.h b/drivers/net/ethernet/mscc/ocelot.h index ba3b3380b4d0..541fe41e60b0 100644 --- a/drivers/net/ethernet/mscc/ocelot.h +++ b/drivers/net/ethernet/mscc/ocelot.h @@ -441,10 +441,6 @@ struct ocelot_port { struct phy_device *phy; void __iomem *regs; u8 chip_port; - /* Keep a track of the mc addresses added to the mac table, so that they - * can be removed when needed. - */ - struct list_head mc; /* Ingress default VLAN (pvid) */ u16 pvid; -- cgit v1.2.3-59-g8ed1b From d008b3d2be4b00267e7af5c21269e7af4f65c6e2 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Tue, 21 May 2019 12:42:56 +0300 Subject: mISDN: Fix indenting in dsp_cmx.c We used a script to indent this code back in 2012, but I guess it got confused by the ifdefs and added some extra tabs. This patch removes them. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/isdn/mISDN/dsp_cmx.c | 427 +++++++++++++++++++++---------------------- 1 file changed, 213 insertions(+), 214 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c index d4b6f01a3f0e..6d2088fbaf69 100644 --- a/drivers/isdn/mISDN/dsp_cmx.c +++ b/drivers/isdn/mISDN/dsp_cmx.c @@ -1676,9 +1676,9 @@ dsp_cmx_send(void *arg) #ifdef CMX_CONF_DEBUG if (conf->software && members > 1) #else - if (conf->software && members > 2) + if (conf->software && members > 2) #endif - mustmix = 1; + mustmix = 1; } /* transmission required */ @@ -1699,263 +1699,262 @@ dsp_cmx_send(void *arg) #ifdef CMX_CONF_DEBUG if (conf->software && members > 1) { #else - if (conf->software && members > 2) { + if (conf->software && members > 2) { #endif - /* check for hdlc conf */ - member = list_entry(conf->mlist.next, - struct dsp_conf_member, list); - if (member->dsp->hdlc) - continue; - /* mix all data */ - memset(mixbuffer, 0, length * sizeof(s32)); - list_for_each_entry(member, &conf->mlist, list) { - dsp = member->dsp; - /* get range of data to mix */ - c = mixbuffer; - q = dsp->rx_buff; - r = dsp->rx_R; - rr = (r + length) & CMX_BUFF_MASK; - /* add member's data */ - while (r != rr) { - *c++ += dsp_audio_law_to_s32[q[r]]; - r = (r + 1) & CMX_BUFF_MASK; - } + /* check for hdlc conf */ + member = list_entry(conf->mlist.next, + struct dsp_conf_member, list); + if (member->dsp->hdlc) + continue; + /* mix all data */ + memset(mixbuffer, 0, length * sizeof(s32)); + list_for_each_entry(member, &conf->mlist, list) { + dsp = member->dsp; + /* get range of data to mix */ + c = mixbuffer; + q = dsp->rx_buff; + r = dsp->rx_R; + rr = (r + length) & CMX_BUFF_MASK; + /* add member's data */ + while (r != rr) { + *c++ += dsp_audio_law_to_s32[q[r]]; + r = (r + 1) & CMX_BUFF_MASK; } + } - /* process each member */ - list_for_each_entry(member, &conf->mlist, list) { - /* transmission */ - dsp_cmx_send_member(member->dsp, length, - mixbuffer, members); - } + /* process each member */ + list_for_each_entry(member, &conf->mlist, list) { + /* transmission */ + dsp_cmx_send_member(member->dsp, length, + mixbuffer, members); + } + } + } + + /* delete rx-data, increment buffers, change pointers */ + list_for_each_entry(dsp, &dsp_ilist, list) { + if (dsp->hdlc) + continue; + p = dsp->rx_buff; + q = dsp->tx_buff; + r = dsp->rx_R; + /* move receive pointer when receiving */ + if (!dsp->rx_is_off) { + rr = (r + length) & CMX_BUFF_MASK; + /* delete rx-data */ + while (r != rr) { + p[r] = dsp_silence; + r = (r + 1) & CMX_BUFF_MASK; } + /* increment rx-buffer pointer */ + dsp->rx_R = r; /* write incremented read pointer */ } - /* delete rx-data, increment buffers, change pointers */ - list_for_each_entry(dsp, &dsp_ilist, list) { - if (dsp->hdlc) - continue; - p = dsp->rx_buff; - q = dsp->tx_buff; - r = dsp->rx_R; - /* move receive pointer when receiving */ - if (!dsp->rx_is_off) { - rr = (r + length) & CMX_BUFF_MASK; + /* check current rx_delay */ + delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK; + if (delay >= CMX_BUFF_HALF) + delay = 0; /* will be the delay before next write */ + /* check for lower delay */ + if (delay < dsp->rx_delay[0]) + dsp->rx_delay[0] = delay; + /* check current tx_delay */ + delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK; + if (delay >= CMX_BUFF_HALF) + delay = 0; /* will be the delay before next write */ + /* check for lower delay */ + if (delay < dsp->tx_delay[0]) + dsp->tx_delay[0] = delay; + if (jittercheck) { + /* find the lowest of all rx_delays */ + delay = dsp->rx_delay[0]; + i = 1; + while (i < MAX_SECONDS_JITTER_CHECK) { + if (delay > dsp->rx_delay[i]) + delay = dsp->rx_delay[i]; + i++; + } + /* + * remove rx_delay only if we have delay AND we + * have not preset cmx_delay AND + * the delay is greater dsp_poll + */ + if (delay > dsp_poll && !dsp->cmx_delay) { + if (dsp_debug & DEBUG_DSP_CLOCK) + printk(KERN_DEBUG + "%s lowest rx_delay of %d bytes for" + " dsp %s are now removed.\n", + __func__, delay, + dsp->name); + r = dsp->rx_R; + rr = (r + delay - (dsp_poll >> 1)) + & CMX_BUFF_MASK; /* delete rx-data */ while (r != rr) { p[r] = dsp_silence; r = (r + 1) & CMX_BUFF_MASK; } /* increment rx-buffer pointer */ - dsp->rx_R = r; /* write incremented read pointer */ + dsp->rx_R = r; + /* write incremented read pointer */ } - - /* check current rx_delay */ - delay = (dsp->rx_W-dsp->rx_R) & CMX_BUFF_MASK; - if (delay >= CMX_BUFF_HALF) - delay = 0; /* will be the delay before next write */ - /* check for lower delay */ - if (delay < dsp->rx_delay[0]) - dsp->rx_delay[0] = delay; - /* check current tx_delay */ - delay = (dsp->tx_W-dsp->tx_R) & CMX_BUFF_MASK; - if (delay >= CMX_BUFF_HALF) - delay = 0; /* will be the delay before next write */ - /* check for lower delay */ - if (delay < dsp->tx_delay[0]) - dsp->tx_delay[0] = delay; - if (jittercheck) { - /* find the lowest of all rx_delays */ - delay = dsp->rx_delay[0]; - i = 1; - while (i < MAX_SECONDS_JITTER_CHECK) { - if (delay > dsp->rx_delay[i]) - delay = dsp->rx_delay[i]; - i++; - } - /* - * remove rx_delay only if we have delay AND we - * have not preset cmx_delay AND - * the delay is greater dsp_poll - */ - if (delay > dsp_poll && !dsp->cmx_delay) { - if (dsp_debug & DEBUG_DSP_CLOCK) - printk(KERN_DEBUG - "%s lowest rx_delay of %d bytes for" - " dsp %s are now removed.\n", - __func__, delay, - dsp->name); - r = dsp->rx_R; - rr = (r + delay - (dsp_poll >> 1)) - & CMX_BUFF_MASK; - /* delete rx-data */ - while (r != rr) { - p[r] = dsp_silence; - r = (r + 1) & CMX_BUFF_MASK; - } - /* increment rx-buffer pointer */ - dsp->rx_R = r; - /* write incremented read pointer */ - } - /* find the lowest of all tx_delays */ - delay = dsp->tx_delay[0]; - i = 1; - while (i < MAX_SECONDS_JITTER_CHECK) { - if (delay > dsp->tx_delay[i]) - delay = dsp->tx_delay[i]; - i++; - } - /* - * remove delay only if we have delay AND we - * have enabled tx_dejitter - */ - if (delay > dsp_poll && dsp->tx_dejitter) { - if (dsp_debug & DEBUG_DSP_CLOCK) - printk(KERN_DEBUG - "%s lowest tx_delay of %d bytes for" - " dsp %s are now removed.\n", - __func__, delay, - dsp->name); - r = dsp->tx_R; - rr = (r + delay - (dsp_poll >> 1)) - & CMX_BUFF_MASK; - /* delete tx-data */ - while (r != rr) { - q[r] = dsp_silence; - r = (r + 1) & CMX_BUFF_MASK; - } - /* increment rx-buffer pointer */ - dsp->tx_R = r; - /* write incremented read pointer */ - } - /* scroll up delays */ - i = MAX_SECONDS_JITTER_CHECK - 1; - while (i) { - dsp->rx_delay[i] = dsp->rx_delay[i - 1]; - dsp->tx_delay[i] = dsp->tx_delay[i - 1]; - i--; + /* find the lowest of all tx_delays */ + delay = dsp->tx_delay[0]; + i = 1; + while (i < MAX_SECONDS_JITTER_CHECK) { + if (delay > dsp->tx_delay[i]) + delay = dsp->tx_delay[i]; + i++; + } + /* + * remove delay only if we have delay AND we + * have enabled tx_dejitter + */ + if (delay > dsp_poll && dsp->tx_dejitter) { + if (dsp_debug & DEBUG_DSP_CLOCK) + printk(KERN_DEBUG + "%s lowest tx_delay of %d bytes for" + " dsp %s are now removed.\n", + __func__, delay, + dsp->name); + r = dsp->tx_R; + rr = (r + delay - (dsp_poll >> 1)) + & CMX_BUFF_MASK; + /* delete tx-data */ + while (r != rr) { + q[r] = dsp_silence; + r = (r + 1) & CMX_BUFF_MASK; } - dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */ - dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */ + /* increment rx-buffer pointer */ + dsp->tx_R = r; + /* write incremented read pointer */ } + /* scroll up delays */ + i = MAX_SECONDS_JITTER_CHECK - 1; + while (i) { + dsp->rx_delay[i] = dsp->rx_delay[i - 1]; + dsp->tx_delay[i] = dsp->tx_delay[i - 1]; + i--; + } + dsp->tx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */ + dsp->rx_delay[0] = CMX_BUFF_HALF; /* (infinite) delay */ } + } - /* if next event would be in the past ... */ - if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0) - dsp_spl_jiffies = jiffies + 1; - else - dsp_spl_jiffies += dsp_tics; + /* if next event would be in the past ... */ + if ((s32)(dsp_spl_jiffies + dsp_tics-jiffies) <= 0) + dsp_spl_jiffies = jiffies + 1; + else + dsp_spl_jiffies += dsp_tics; - dsp_spl_tl.expires = dsp_spl_jiffies; - add_timer(&dsp_spl_tl); + dsp_spl_tl.expires = dsp_spl_jiffies; + add_timer(&dsp_spl_tl); - /* unlock */ - spin_unlock_irqrestore(&dsp_lock, flags); - } + /* unlock */ + spin_unlock_irqrestore(&dsp_lock, flags); +} /* * audio data is transmitted from upper layer to the dsp */ - void - dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb) - { - u_int w, ww; - u8 *d, *p; - int space; /* todo: , l = skb->len; */ +void +dsp_cmx_transmit(struct dsp *dsp, struct sk_buff *skb) +{ + u_int w, ww; + u8 *d, *p; + int space; /* todo: , l = skb->len; */ #ifdef CMX_TX_DEBUG - char debugbuf[256] = ""; + char debugbuf[256] = ""; #endif - /* check if there is enough space, and then copy */ - w = dsp->tx_W; - ww = dsp->tx_R; - p = dsp->tx_buff; - d = skb->data; - space = (ww - w - 1) & CMX_BUFF_MASK; - /* write-pointer should not overrun nor reach read pointer */ - if (space < skb->len) { - /* write to the space we have left */ - ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */ - if (dsp_debug & DEBUG_DSP_CLOCK) - printk(KERN_DEBUG "%s: TX overflow space=%d skb->len=" - "%d, w=0x%04x, ww=0x%04x\n", __func__, space, - skb->len, w, ww); - } else - /* write until all byte are copied */ - ww = (w + skb->len) & CMX_BUFF_MASK; - dsp->tx_W = ww; - + /* check if there is enough space, and then copy */ + w = dsp->tx_W; + ww = dsp->tx_R; + p = dsp->tx_buff; + d = skb->data; + space = (ww - w - 1) & CMX_BUFF_MASK; + /* write-pointer should not overrun nor reach read pointer */ + if (space < skb->len) { + /* write to the space we have left */ + ww = (ww - 1) & CMX_BUFF_MASK; /* end one byte prior tx_R */ + if (dsp_debug & DEBUG_DSP_CLOCK) + printk(KERN_DEBUG "%s: TX overflow space=%d skb->len=" + "%d, w=0x%04x, ww=0x%04x\n", __func__, space, + skb->len, w, ww); + } else + /* write until all byte are copied */ + ww = (w + skb->len) & CMX_BUFF_MASK; + dsp->tx_W = ww; /* show current buffer */ #ifdef CMX_DEBUG - printk(KERN_DEBUG - "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n", - (u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name); + printk(KERN_DEBUG + "cmx_transmit(dsp=%lx) %d bytes to 0x%x-0x%x. %s\n", + (u_long)dsp, (ww - w) & CMX_BUFF_MASK, w, ww, dsp->name); #endif - /* copy transmit data to tx-buffer */ + /* copy transmit data to tx-buffer */ #ifdef CMX_TX_DEBUG - sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p); + sprintf(debugbuf, "TX getting (%04x-%04x)%p: ", w, ww, p); #endif - while (w != ww) { + while (w != ww) { #ifdef CMX_TX_DEBUG - if (strlen(debugbuf) < 48) - sprintf(debugbuf + strlen(debugbuf), " %02x", *d); + if (strlen(debugbuf) < 48) + sprintf(debugbuf + strlen(debugbuf), " %02x", *d); #endif - p[w] = *d++; - w = (w + 1) & CMX_BUFF_MASK; - } + p[w] = *d++; + w = (w + 1) & CMX_BUFF_MASK; + } #ifdef CMX_TX_DEBUG - printk(KERN_DEBUG "%s\n", debugbuf); + printk(KERN_DEBUG "%s\n", debugbuf); #endif - } +} /* * hdlc data is received from card and sent to all members. */ - void - dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb) - { - struct sk_buff *nskb = NULL; - struct dsp_conf_member *member; - struct mISDNhead *hh; - - /* not if not active */ - if (!dsp->b_active) - return; +void +dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb) +{ + struct sk_buff *nskb = NULL; + struct dsp_conf_member *member; + struct mISDNhead *hh; - /* check if we have sompen */ - if (skb->len < 1) - return; + /* not if not active */ + if (!dsp->b_active) + return; - /* no conf */ - if (!dsp->conf) { - /* in case of software echo */ - if (dsp->echo.software) { - nskb = skb_clone(skb, GFP_ATOMIC); - if (nskb) { - hh = mISDN_HEAD_P(nskb); - hh->prim = PH_DATA_REQ; - hh->id = 0; - skb_queue_tail(&dsp->sendq, nskb); - schedule_work(&dsp->workq); - } + /* check if we have sompen */ + if (skb->len < 1) + return; + + /* no conf */ + if (!dsp->conf) { + /* in case of software echo */ + if (dsp->echo.software) { + nskb = skb_clone(skb, GFP_ATOMIC); + if (nskb) { + hh = mISDN_HEAD_P(nskb); + hh->prim = PH_DATA_REQ; + hh->id = 0; + skb_queue_tail(&dsp->sendq, nskb); + schedule_work(&dsp->workq); } - return; } - /* in case of hardware conference */ - if (dsp->conf->hardware) - return; - list_for_each_entry(member, &dsp->conf->mlist, list) { - if (dsp->echo.software || member->dsp != dsp) { - nskb = skb_clone(skb, GFP_ATOMIC); - if (nskb) { - hh = mISDN_HEAD_P(nskb); - hh->prim = PH_DATA_REQ; - hh->id = 0; - skb_queue_tail(&member->dsp->sendq, nskb); - schedule_work(&member->dsp->workq); - } + return; + } + /* in case of hardware conference */ + if (dsp->conf->hardware) + return; + list_for_each_entry(member, &dsp->conf->mlist, list) { + if (dsp->echo.software || member->dsp != dsp) { + nskb = skb_clone(skb, GFP_ATOMIC); + if (nskb) { + hh = mISDN_HEAD_P(nskb); + hh->prim = PH_DATA_REQ; + hh->id = 0; + skb_queue_tail(&member->dsp->sendq, nskb); + schedule_work(&member->dsp->workq); } } } +} -- cgit v1.2.3-59-g8ed1b From c1e85c6ce57ef1eb73966152993a341c8123a8ea Mon Sep 17 00:00:00 2001 From: Claudiu Beznea Date: Wed, 22 May 2019 08:24:43 +0000 Subject: net: macb: save/restore the remaining registers and features SAMA5D2 SoC has a suspend mode where SoC's power is cut off. Due to this the registers content is lost after a suspend/resume cycle. The current suspend/resume implementation covers some of these registers. However there are few which were not treated (e.g. SCRT2 and USRIO). Apart from this, netdev features are not restored. Treat these issues. Signed-off-by: Claudiu Beznea Signed-off-by: David S. Miller --- drivers/net/ethernet/cadence/macb.h | 7 ++ drivers/net/ethernet/cadence/macb_main.c | 111 +++++++++++++++++++++++-------- 2 files changed, 91 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h index acc66a7e7b95..00ee5e8e0ff0 100644 --- a/drivers/net/ethernet/cadence/macb.h +++ b/drivers/net/ethernet/cadence/macb.h @@ -1080,6 +1080,11 @@ struct macb_ptp_info { struct ifreq *ifr, int cmd); }; +struct macb_pm_data { + u32 scrt2; + u32 usrio; +}; + struct macb_config { u32 caps; unsigned int dma_burst_length; @@ -1220,6 +1225,8 @@ struct macb { int tx_bd_rd_prefetch; u32 rx_intr_mask; + + struct macb_pm_data pm_data; }; #ifdef CONFIG_MACB_USE_HWSTAMP diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index bebd9b1aeb64..f825e3960540 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -2849,10 +2849,14 @@ static int macb_get_ts_info(struct net_device *netdev, static void gem_enable_flow_filters(struct macb *bp, bool enable) { + struct net_device *netdev = bp->dev; struct ethtool_rx_fs_item *item; u32 t2_scr; int num_t2_scr; + if (!(netdev->features & NETIF_F_NTUPLE)) + return; + num_t2_scr = GEM_BFEXT(T2SCR, gem_readl(bp, DCFG8)); list_for_each_entry(item, &bp->rx_fs_list.list, list) { @@ -3012,8 +3016,7 @@ static int gem_add_flow_filter(struct net_device *netdev, gem_prog_cmp_regs(bp, fs); bp->rx_fs_list.count++; /* enable filtering if NTUPLE on */ - if (netdev->features & NETIF_F_NTUPLE) - gem_enable_flow_filters(bp, 1); + gem_enable_flow_filters(bp, 1); spin_unlock_irqrestore(&bp->rx_fs_lock, flags); return 0; @@ -3201,6 +3204,50 @@ static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) } } +static inline void macb_set_txcsum_feature(struct macb *bp, + netdev_features_t features) +{ + u32 val; + + if (!macb_is_gem(bp)) + return; + + val = gem_readl(bp, DMACFG); + if (features & NETIF_F_HW_CSUM) + val |= GEM_BIT(TXCOEN); + else + val &= ~GEM_BIT(TXCOEN); + + gem_writel(bp, DMACFG, val); +} + +static inline void macb_set_rxcsum_feature(struct macb *bp, + netdev_features_t features) +{ + struct net_device *netdev = bp->dev; + u32 val; + + if (!macb_is_gem(bp)) + return; + + val = gem_readl(bp, NCFGR); + if ((features & NETIF_F_RXCSUM) && !(netdev->flags & IFF_PROMISC)) + val |= GEM_BIT(RXCOEN); + else + val &= ~GEM_BIT(RXCOEN); + + gem_writel(bp, NCFGR, val); +} + +static inline void macb_set_rxflow_feature(struct macb *bp, + netdev_features_t features) +{ + if (!macb_is_gem(bp)) + return; + + gem_enable_flow_filters(bp, !!(features & NETIF_F_NTUPLE)); +} + static int macb_set_features(struct net_device *netdev, netdev_features_t features) { @@ -3208,39 +3255,35 @@ static int macb_set_features(struct net_device *netdev, netdev_features_t changed = features ^ netdev->features; /* TX checksum offload */ - if ((changed & NETIF_F_HW_CSUM) && macb_is_gem(bp)) { - u32 dmacfg; - - dmacfg = gem_readl(bp, DMACFG); - if (features & NETIF_F_HW_CSUM) - dmacfg |= GEM_BIT(TXCOEN); - else - dmacfg &= ~GEM_BIT(TXCOEN); - gem_writel(bp, DMACFG, dmacfg); - } + if (changed & NETIF_F_HW_CSUM) + macb_set_txcsum_feature(bp, features); /* RX checksum offload */ - if ((changed & NETIF_F_RXCSUM) && macb_is_gem(bp)) { - u32 netcfg; - - netcfg = gem_readl(bp, NCFGR); - if (features & NETIF_F_RXCSUM && - !(netdev->flags & IFF_PROMISC)) - netcfg |= GEM_BIT(RXCOEN); - else - netcfg &= ~GEM_BIT(RXCOEN); - gem_writel(bp, NCFGR, netcfg); - } + if (changed & NETIF_F_RXCSUM) + macb_set_rxcsum_feature(bp, features); /* RX Flow Filters */ - if ((changed & NETIF_F_NTUPLE) && macb_is_gem(bp)) { - bool turn_on = features & NETIF_F_NTUPLE; + if (changed & NETIF_F_NTUPLE) + macb_set_rxflow_feature(bp, features); - gem_enable_flow_filters(bp, turn_on); - } return 0; } +static void macb_restore_features(struct macb *bp) +{ + struct net_device *netdev = bp->dev; + netdev_features_t features = netdev->features; + + /* TX checksum offload */ + macb_set_txcsum_feature(bp, features); + + /* RX checksum offload */ + macb_set_rxcsum_feature(bp, features); + + /* RX Flow Filters */ + macb_set_rxflow_feature(bp, features); +} + static const struct net_device_ops macb_netdev_ops = { .ndo_open = macb_open, .ndo_stop = macb_close, @@ -4273,6 +4316,12 @@ static int __maybe_unused macb_suspend(struct device *dev) spin_lock_irqsave(&bp->lock, flags); macb_reset_hw(bp); spin_unlock_irqrestore(&bp->lock, flags); + + if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) + bp->pm_data.usrio = macb_or_gem_readl(bp, USRIO); + + if (netdev->hw_features & NETIF_F_NTUPLE) + bp->pm_data.scrt2 = gem_readl_n(bp, ETHT, SCRT2_ETHT); } netif_carrier_off(netdev); @@ -4301,6 +4350,13 @@ static int __maybe_unused macb_resume(struct device *dev) disable_irq_wake(bp->queues[0].irq); } else { macb_writel(bp, NCR, MACB_BIT(MPE)); + + if (netdev->hw_features & NETIF_F_NTUPLE) + gem_writel_n(bp, ETHT, SCRT2_ETHT, bp->pm_data.scrt2); + + if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) + macb_or_gem_writel(bp, USRIO, bp->pm_data.usrio); + for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) napi_enable(&queue->napi); @@ -4312,6 +4368,7 @@ static int __maybe_unused macb_resume(struct device *dev) bp->macbgem_ops.mog_init_rings(bp); macb_init_hw(bp); macb_set_rx_mode(netdev); + macb_restore_features(bp); netif_device_attach(netdev); if (bp->ptp_info) bp->ptp_info->ptp_init(netdev); -- cgit v1.2.3-59-g8ed1b From ccfb62f27beb295103e9392462b20a6ed807d0ea Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 22 May 2019 11:45:13 +0300 Subject: mISDN: make sure device name is NUL terminated The user can change the device_name with the IMSETDEVNAME ioctl, but we need to ensure that the user's name is NUL terminated. Otherwise it could result in a buffer overflow when we copy the name back to the user with IMGETDEVINFO ioctl. I also changed two strcpy() calls which handle the name to strscpy(). Hopefully, there aren't any other ways to create a too long name, but it's nice to do this as a kernel hardening measure. Signed-off-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/isdn/mISDN/socket.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/mISDN/socket.c b/drivers/isdn/mISDN/socket.c index a14e35d40538..84e1d4c2db66 100644 --- a/drivers/isdn/mISDN/socket.c +++ b/drivers/isdn/mISDN/socket.c @@ -393,7 +393,7 @@ data_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) memcpy(di.channelmap, dev->channelmap, sizeof(di.channelmap)); di.nrbchan = dev->nrbchan; - strcpy(di.name, dev_name(&dev->dev)); + strscpy(di.name, dev_name(&dev->dev), sizeof(di.name)); if (copy_to_user((void __user *)arg, &di, sizeof(di))) err = -EFAULT; } else @@ -676,7 +676,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) memcpy(di.channelmap, dev->channelmap, sizeof(di.channelmap)); di.nrbchan = dev->nrbchan; - strcpy(di.name, dev_name(&dev->dev)); + strscpy(di.name, dev_name(&dev->dev), sizeof(di.name)); if (copy_to_user((void __user *)arg, &di, sizeof(di))) err = -EFAULT; } else @@ -690,6 +690,7 @@ base_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) err = -EFAULT; break; } + dn.name[sizeof(dn.name) - 1] = '\0'; dev = get_mdevice(dn.id); if (dev) err = device_rename(&dev->dev, dn.name); -- cgit v1.2.3-59-g8ed1b From 49ce881c0d4c4a7a35358d9dccd5f26d0e56fc61 Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Wed, 22 May 2019 10:05:09 +0000 Subject: net: stmmac: fix reset gpio free missing Commit 984203ceff27 ("net: stmmac: mdio: remove reset gpio free") removed the reset gpio free, when the driver is unbinded or rmmod, we miss the gpio free. This patch uses managed API to request the reset gpio, so that the gpio could be freed properly. Fixes: 984203ceff27 ("net: stmmac: mdio: remove reset gpio free") Signed-off-by: Jisheng Zhang Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c index bdd351597b55..093a223fe408 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c @@ -267,7 +267,8 @@ int stmmac_mdio_reset(struct mii_bus *bus) of_property_read_u32_array(np, "snps,reset-delays-us", data->delays, 3); - if (gpio_request(data->reset_gpio, "mdio-reset")) + if (devm_gpio_request(priv->device, data->reset_gpio, + "mdio-reset")) return 0; } -- cgit v1.2.3-59-g8ed1b From 296d5b54163964b7ae536b8b57dfbd21d4e868e1 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 22 May 2019 19:12:54 -0400 Subject: bnxt_en: Fix aggregation buffer leak under OOM condition. For every RX packet, the driver replenishes all buffers used for that packet and puts them back into the RX ring and RX aggregation ring. In one code path where the RX packet has one RX buffer and one or more aggregation buffers, we missed recycling the aggregation buffer(s) if we are unable to allocate a new SKB buffer. This leads to the aggregation ring slowly running out of buffers over time. Fix it by properly recycling the aggregation buffers. Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.") Reported-by: Rakesh Hemnani Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 8314c00d7537..21f682610e6a 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -1642,6 +1642,8 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, skb = bnxt_copy_skb(bnapi, data_ptr, len, dma_addr); bnxt_reuse_rx_data(rxr, cons, data); if (!skb) { + if (agg_bufs) + bnxt_reuse_rx_agg_bufs(cpr, cp_cons, agg_bufs); rc = -ENOMEM; goto next_rx; } -- cgit v1.2.3-59-g8ed1b From 1b3f0b75c39f534278a895c117282014e9d0ae1f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 22 May 2019 19:12:55 -0400 Subject: bnxt_en: Fix possible BUG() condition when calling pci_disable_msix(). When making configuration changes, the driver calls bnxt_close_nic() and then bnxt_open_nic() for the changes to take effect. A parameter irq_re_init is passed to the call sequence to indicate if IRQ should be re-initialized. This irq_re_init parameter needs to be included in the bnxt_reserve_rings() call. bnxt_reserve_rings() can only call pci_disable_msix() if the irq_re_init parameter is true, otherwise it may hit BUG() because some IRQs may not have been freed yet. Fixes: 41e8d7983752 ("bnxt_en: Modify the ring reservation functions for 57500 series chips.") Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 13 +++++++------ drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 2 +- drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c | 2 +- 4 files changed, 10 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 21f682610e6a..cfcc33c52685 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -7618,22 +7618,23 @@ static void bnxt_clear_int_mode(struct bnxt *bp) bp->flags &= ~BNXT_FLAG_USING_MSIX; } -int bnxt_reserve_rings(struct bnxt *bp) +int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init) { int tcs = netdev_get_num_tc(bp->dev); - bool reinit_irq = false; + bool irq_cleared = false; int rc; if (!bnxt_need_reserve_rings(bp)) return 0; - if (BNXT_NEW_RM(bp) && (bnxt_get_num_msix(bp) != bp->total_irqs)) { + if (irq_re_init && BNXT_NEW_RM(bp) && + bnxt_get_num_msix(bp) != bp->total_irqs) { bnxt_ulp_irq_stop(bp); bnxt_clear_int_mode(bp); - reinit_irq = true; + irq_cleared = true; } rc = __bnxt_reserve_rings(bp); - if (reinit_irq) { + if (irq_cleared) { if (!rc) rc = bnxt_init_int_mode(bp); bnxt_ulp_irq_restart(bp, rc); @@ -8532,7 +8533,7 @@ static int __bnxt_open_nic(struct bnxt *bp, bool irq_re_init, bool link_re_init) return rc; } } - rc = bnxt_reserve_rings(bp); + rc = bnxt_reserve_rings(bp, irq_re_init); if (rc) return rc; if ((bp->flags & BNXT_FLAG_RFS) && diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index eca36dd6b751..acc73f301783 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1790,7 +1790,7 @@ unsigned int bnxt_get_avail_stat_ctxs_for_en(struct bnxt *bp); unsigned int bnxt_get_max_func_cp_rings(struct bnxt *bp); unsigned int bnxt_get_avail_cp_rings_for_en(struct bnxt *bp); int bnxt_get_avail_msix(struct bnxt *bp, int num); -int bnxt_reserve_rings(struct bnxt *bp); +int bnxt_reserve_rings(struct bnxt *bp, bool irq_re_init); void bnxt_tx_disable(struct bnxt *bp); void bnxt_tx_enable(struct bnxt *bp); int bnxt_hwrm_set_pause(struct bnxt *); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index b1263821a6e9..a6c7baf38036 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -831,7 +831,7 @@ static int bnxt_set_channels(struct net_device *dev, */ } } else { - rc = bnxt_reserve_rings(bp); + rc = bnxt_reserve_rings(bp, true); } return rc; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c index cf475873ce81..bfa342a98d08 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ulp.c @@ -147,7 +147,7 @@ static int bnxt_req_msix_vecs(struct bnxt_en_dev *edev, int ulp_id, bnxt_close_nic(bp, true, false); rc = bnxt_open_nic(bp, true, false); } else { - rc = bnxt_reserve_rings(bp); + rc = bnxt_reserve_rings(bp, true); } } if (rc) { -- cgit v1.2.3-59-g8ed1b From d629522e1d66561f38e5c8d4f52bb6d254ec0707 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Wed, 22 May 2019 19:12:56 -0400 Subject: bnxt_en: Reduce memory usage when running in kdump kernel. Skip RDMA context memory allocations, reduce to 1 ring, and disable TPA when running in the kdump kernel. Without this patch, the driver fails to initialize with memory allocation errors when running in a typical kdump kernel. Fixes: cf6daed098d1 ("bnxt_en: Increase context memory allocations on 57500 chips for RDMA.") Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 4 ++-- drivers/net/ethernet/broadcom/bnxt/bnxt.h | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index cfcc33c52685..79812daa4127 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -6379,7 +6379,7 @@ static int bnxt_alloc_ctx_mem(struct bnxt *bp) if (!ctx || (ctx->flags & BNXT_CTX_FLAG_INITED)) return 0; - if (bp->flags & BNXT_FLAG_ROCE_CAP) { + if ((bp->flags & BNXT_FLAG_ROCE_CAP) && !is_kdump_kernel()) { pg_lvl = 2; extra_qps = 65536; extra_srqs = 8192; @@ -10437,7 +10437,7 @@ static int bnxt_set_dflt_rings(struct bnxt *bp, bool sh) if (sh) bp->flags |= BNXT_FLAG_SHARED_RINGS; - dflt_rings = netif_get_num_default_rss_queues(); + dflt_rings = is_kdump_kernel() ? 1 : netif_get_num_default_rss_queues(); /* Reduce default rings on multi-port cards so that total default * rings do not exceed CPU count. */ diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index acc73f301783..be438d82f939 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -20,6 +20,7 @@ #include #include +#include #include #include #include @@ -1369,7 +1370,8 @@ struct bnxt { #define BNXT_CHIP_TYPE_NITRO_A0(bp) ((bp)->flags & BNXT_FLAG_CHIP_NITRO_A0) #define BNXT_RX_PAGE_MODE(bp) ((bp)->flags & BNXT_FLAG_RX_PAGE_MODE) #define BNXT_SUPPORTS_TPA(bp) (!BNXT_CHIP_TYPE_NITRO_A0(bp) && \ - !(bp->flags & BNXT_FLAG_CHIP_P5)) + !(bp->flags & BNXT_FLAG_CHIP_P5) && \ + !is_kdump_kernel()) /* Chip class phase 5 */ #define BNXT_CHIP_P5(bp) \ -- cgit v1.2.3-59-g8ed1b From 2e9217d1e8b72dde2c7e3e2338cc1830f68cb58d Mon Sep 17 00:00:00 2001 From: Vasundhara Volam Date: Wed, 22 May 2019 19:12:57 -0400 Subject: bnxt_en: Device serial number is supported only for PFs. Don't read DSN on VFs that do not have the PCI capability. Fixes: 03213a996531 ("bnxt: move bp->switch_id initialization to PF probe") Signed-off-by: Vasundhara Volam Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 79812daa4127..f758b2e0591f 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -10725,11 +10725,12 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) goto init_err_pci_clean; } - /* Read the adapter's DSN to use as the eswitch switch_id */ - rc = bnxt_pcie_dsn_get(bp, bp->switch_id); - if (rc) - goto init_err_pci_clean; - + if (BNXT_PF(bp)) { + /* Read the adapter's DSN to use as the eswitch switch_id */ + rc = bnxt_pcie_dsn_get(bp, bp->switch_id); + if (rc) + goto init_err_pci_clean; + } bnxt_hwrm_func_qcfg(bp); bnxt_hwrm_vnic_qcaps(bp); bnxt_hwrm_port_led_qcaps(bp); -- cgit v1.2.3-59-g8ed1b From 3f6f7a175ad4cf9a6a3dda72d7f5d122107f4b9e Mon Sep 17 00:00:00 2001 From: Maxime Chevallier Date: Thu, 23 May 2019 10:47:24 +0200 Subject: net: mvpp2: cls: Fix leaked ethtool_rx_flow_rule The flow_rule is only used when configuring the classification tables, and should be free'd once we're done using it. The current code only frees it in the error path. Fixes: 90b509b39ac9 ("net: mvpp2: cls: Add Classification offload support") Signed-off-by: Maxime Chevallier Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c index d046f7a1dcf5..a57d17ab91f0 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c @@ -1271,6 +1271,9 @@ int mvpp2_ethtool_cls_rule_ins(struct mvpp2_port *port, if (ret) goto clean_eth_rule; + ethtool_rx_flow_rule_destroy(ethtool_rule); + efs->rule.flow = NULL; + memcpy(&efs->rxnfc, info, sizeof(*info)); port->rfs_rules[efs->rule.loc] = efs; port->n_rfs_rules++; -- cgit v1.2.3-59-g8ed1b From b5730061d1056abf317caea823b94d6e12b5b4f6 Mon Sep 17 00:00:00 2001 From: Raju Rangoju Date: Thu, 23 May 2019 20:41:44 +0530 Subject: cxgb4: offload VLAN flows regardless of VLAN ethtype VLAN flows never get offloaded unless ivlan_vld is set in filter spec. It's not compulsory for vlan_ethtype to be set. So, always enable ivlan_vld bit for offloading VLAN flows regardless of vlan_ethtype is set or not. Fixes: ad9af3e09c (cxgb4: add tc flower match support for vlan) Signed-off-by: Raju Rangoju Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c index 6e2d80008a79..cfaf8f618d1f 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c @@ -197,6 +197,9 @@ static void cxgb4_process_flow_match(struct net_device *dev, fs->val.ivlan = vlan_tci; fs->mask.ivlan = vlan_tci_mask; + fs->val.ivlan_vld = 1; + fs->mask.ivlan_vld = 1; + /* Chelsio adapters use ivlan_vld bit to match vlan packets * as 802.1Q. Also, when vlan tag is present in packets, * ethtype match is used then to match on ethtype of inner @@ -207,8 +210,6 @@ static void cxgb4_process_flow_match(struct net_device *dev, * ethtype value with ethtype of inner header. */ if (fs->val.ethtype == ETH_P_8021Q) { - fs->val.ivlan_vld = 1; - fs->mask.ivlan_vld = 1; fs->val.ethtype = 0; fs->mask.ethtype = 0; } -- cgit v1.2.3-59-g8ed1b From ce8d24f9a5965a58c588f9342689702a1024433c Mon Sep 17 00:00:00 2001 From: Andy Duan Date: Thu, 23 May 2019 01:55:28 +0000 Subject: net: fec: fix the clk mismatch in failed_reset path Fix the clk mismatch in the error path "failed_reset" because below error path will disable clk_ahb and clk_ipg directly, it should use pm_runtime_put_noidle() instead of pm_runtime_put() to avoid to call runtime resume callback. Reported-by: Baruch Siach Signed-off-by: Fugang Duan Tested-by: Baruch Siach Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c index aa7d4e27c5d1..38f10f7dcbc3 100644 --- a/drivers/net/ethernet/freescale/fec_main.c +++ b/drivers/net/ethernet/freescale/fec_main.c @@ -3556,7 +3556,7 @@ failed_init: if (fep->reg_phy) regulator_disable(fep->reg_phy); failed_reset: - pm_runtime_put(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); failed_regulator: clk_disable_unprepare(fep->clk_ahb); -- cgit v1.2.3-59-g8ed1b From ab0610efabb4c4f419a531455708caf1dd29357e Mon Sep 17 00:00:00 2001 From: Vishal Kulkarni Date: Thu, 23 May 2019 08:07:21 +0530 Subject: cxgb4: Revert "cxgb4: Remove SGE_HOST_PAGE_SIZE dependency on page size" This reverts commit 2391b0030e241386d710df10e53e2cfc3c5d4fc1 which has introduced regression. Now SGE's BAR2 Doorbell/GTS Page Size is interpreted correctly in the firmware itself by using actual host page size. Hence previous commit needs to be reverted. Signed-off-by: Vishal Kulkarni Signed-off-by: David S. Miller --- drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c index f9b70be59792..93feb258067b 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c +++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c @@ -7253,10 +7253,21 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size, unsigned int cache_line_size) { unsigned int page_shift = fls(page_size) - 1; + unsigned int sge_hps = page_shift - 10; unsigned int stat_len = cache_line_size > 64 ? 128 : 64; unsigned int fl_align = cache_line_size < 32 ? 32 : cache_line_size; unsigned int fl_align_log = fls(fl_align) - 1; + t4_write_reg(adap, SGE_HOST_PAGE_SIZE_A, + HOSTPAGESIZEPF0_V(sge_hps) | + HOSTPAGESIZEPF1_V(sge_hps) | + HOSTPAGESIZEPF2_V(sge_hps) | + HOSTPAGESIZEPF3_V(sge_hps) | + HOSTPAGESIZEPF4_V(sge_hps) | + HOSTPAGESIZEPF5_V(sge_hps) | + HOSTPAGESIZEPF6_V(sge_hps) | + HOSTPAGESIZEPF7_V(sge_hps)); + if (is_t4(adap->params.chip)) { t4_set_reg_field(adap, SGE_CONTROL_A, INGPADBOUNDARY_V(INGPADBOUNDARY_M) | -- cgit v1.2.3-59-g8ed1b From 4523a5611526709ec9b4e2574f1bb7818212651e Mon Sep 17 00:00:00 2001 From: Biao Huang Date: Fri, 24 May 2019 14:26:07 +0800 Subject: net: stmmac: update rx tail pointer register to fix rx dma hang issue. Currently we will not update the receive descriptor tail pointer in stmmac_rx_refill. Rx dma will think no available descriptors and stop once received packets exceed DMA_RX_SIZE, so that the rx only test will fail. Update the receive tail pointer in stmmac_rx_refill to add more descriptors to the rx channel, so packets can be received continually Fixes: 54139cf3bb33 ("net: stmmac: adding multiple buffers for rx") Signed-off-by: Biao Huang Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 2a1052704885..bc93c355f403 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -3338,6 +3338,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue) entry = STMMAC_GET_ENTRY(entry, DMA_RX_SIZE); } rx_q->dirty_rx = entry; + stmmac_set_rx_tail_ptr(priv, priv->ioaddr, rx_q->rx_tail_addr, queue); } /** -- cgit v1.2.3-59-g8ed1b From 5e7f7fc538d894b2d9aa41876b8dcf35f5fe11e6 Mon Sep 17 00:00:00 2001 From: Biao Huang Date: Fri, 24 May 2019 14:26:08 +0800 Subject: net: stmmac: fix csr_clk can't be zero issue The specific clk_csr value can be zero, and stmmac_clk is necessary for MDC clock which can be set dynamically. So, change the condition from plat->clk_csr to plat->stmmac_clk to fix clk_csr can't be zero issue. Fixes: cd7201f477b9 ("stmmac: MDC clock dynamically based on the csr clock input") Signed-off-by: Biao Huang Acked-by: Alexandre TORGUE Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 6 +++--- drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index bc93c355f403..65e57b9f6887 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -4380,10 +4380,10 @@ int stmmac_dvr_probe(struct device *device, * set the MDC clock dynamically according to the csr actual * clock input. */ - if (!priv->plat->clk_csr) - stmmac_clk_csr_set(priv); - else + if (priv->plat->clk_csr >= 0) priv->clk_csr = priv->plat->clk_csr; + else + stmmac_clk_csr_set(priv); stmmac_check_pcs_mode(priv); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 3031f2bf15d6..f45bfbef97d0 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -408,7 +408,10 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) /* Default to phy auto-detection */ plat->phy_addr = -1; - /* Get clk_csr from device tree */ + /* Default to get clk_csr from stmmac_clk_crs_set(), + * or get clk_csr from device tree. + */ + plat->clk_csr = -1; of_property_read_u32(np, "clk_csr", &plat->clk_csr); /* "snps,phy-addr" is not a standard property. Mark it as deprecated -- cgit v1.2.3-59-g8ed1b From f4ca7a9260dfe700f2a16f0881825de625067515 Mon Sep 17 00:00:00 2001 From: Biao Huang Date: Fri, 24 May 2019 14:26:09 +0800 Subject: net: stmmac: dwmac-mediatek: modify csr_clk value to fix mdio read/write fail 1. the frequency of csr clock is 66.5MHz, so the csr_clk value should be 0 other than 5. 2. the csr_clk can be got from device tree, so remove initialization here. Fixes: 9992f37e346b ("stmmac: dwmac-mediatek: add support for mt2712") Signed-off-by: Biao Huang Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c index bf2562995fc8..126b66bb73a6 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-mediatek.c @@ -346,8 +346,6 @@ static int mediatek_dwmac_probe(struct platform_device *pdev) return PTR_ERR(plat_dat); plat_dat->interface = priv_plat->phy_mode; - /* clk_csr_i = 250-300MHz & MDC = clk_csr_i/124 */ - plat_dat->clk_csr = 5; plat_dat->has_gmac4 = 1; plat_dat->has_gmac = 0; plat_dat->pmt = 0; -- cgit v1.2.3-59-g8ed1b From 334031219a84b9994594015aab85ed7754c80176 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 24 May 2019 09:49:28 -0400 Subject: bonding/802.3ad: fix slave link initialization transition states Once in a while, with just the right timing, 802.3ad slaves will fail to properly initialize, winding up in a weird state, with a partner system mac address of 00:00:00:00:00:00. This started happening after a fix to properly track link_failure_count tracking, where an 802.3ad slave that reported itself as link up in the miimon code, but wasn't able to get a valid speed/duplex, started getting set to BOND_LINK_FAIL instead of BOND_LINK_DOWN. That was the proper thing to do for the general "my link went down" case, but has created a link initialization race that can put the interface in this odd state. The simple fix is to instead set the slave link to BOND_LINK_DOWN again, if the link has never been up (last_link_up == 0), so the link state doesn't bounce from BOND_LINK_DOWN to BOND_LINK_FAIL -- it hasn't failed in this case, it simply hasn't been up yet, and this prevents the unnecessary state change from DOWN to FAIL and getting stuck in an init failure w/o a partner mac. Fixes: ea53abfab960 ("bonding/802.3ad: fix link_failure_count tracking") CC: Jay Vosburgh CC: Veaceslav Falico CC: Andy Gospodarek CC: "David S. Miller" CC: netdev@vger.kernel.org Tested-by: Heesoon Kim Signed-off-by: Jarod Wilson Acked-by: Jay Vosburgh Signed-off-by: David S. Miller --- drivers/net/bonding/bond_main.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 062fa7e3af4c..407f4095a37a 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c @@ -3122,13 +3122,18 @@ static int bond_slave_netdev_event(unsigned long event, case NETDEV_CHANGE: /* For 802.3ad mode only: * Getting invalid Speed/Duplex values here will put slave - * in weird state. So mark it as link-fail for the time - * being and let link-monitoring (miimon) set it right when - * correct speeds/duplex are available. + * in weird state. Mark it as link-fail if the link was + * previously up or link-down if it hasn't yet come up, and + * let link-monitoring (miimon) set it right when correct + * speeds/duplex are available. */ if (bond_update_speed_duplex(slave) && - BOND_MODE(bond) == BOND_MODE_8023AD) - slave->link = BOND_LINK_FAIL; + BOND_MODE(bond) == BOND_MODE_8023AD) { + if (slave->last_link_up) + slave->link = BOND_LINK_FAIL; + else + slave->link = BOND_LINK_DOWN; + } if (BOND_MODE(bond) == BOND_MODE_8023AD) bond_3ad_adapter_speed_duplex_changed(slave); -- cgit v1.2.3-59-g8ed1b From 5a20a093d965560f632b2ec325f8876918f78165 Mon Sep 17 00:00:00 2001 From: Ioana Radulescu Date: Fri, 24 May 2019 18:15:15 +0300 Subject: dpaa2-eth: Fix potential spectre issue Smatch reports a potential spectre vulnerability in the dpaa2-eth driver, where the value of rxnfc->fs.location (which is provided from user-space) is used as index in an array. Add a call to array_index_nospec() to sanitize the access. Signed-off-by: Ioana Radulescu Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c index 76bd8d2872cc..7b182f4b263c 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c @@ -4,6 +4,7 @@ */ #include +#include #include "dpni.h" /* DPNI_LINK_OPT_* */ #include "dpaa2-eth.h" @@ -648,6 +649,8 @@ static int dpaa2_eth_get_rxnfc(struct net_device *net_dev, case ETHTOOL_GRXCLSRULE: if (rxnfc->fs.location >= max_rules) return -EINVAL; + rxnfc->fs.location = array_index_nospec(rxnfc->fs.location, + max_rules); if (!priv->cls_rules[rxnfc->fs.location].in_use) return -EINVAL; rxnfc->fs = priv->cls_rules[rxnfc->fs.location].fs; -- cgit v1.2.3-59-g8ed1b From bd8460fa4de46e9d6177af4fe33bf0763a7af4b7 Mon Sep 17 00:00:00 2001 From: Ioana Radulescu Date: Fri, 24 May 2019 18:15:16 +0300 Subject: dpaa2-eth: Use PTR_ERR_OR_ZERO where appropriate Use PTR_ERR_OR_ZERO instead of PTR_ERR in cases where zero is a valid input. Reported by smatch. Signed-off-by: Ioana Radulescu Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c index 63b1ecc18c26..7d2390e3df77 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c @@ -1972,7 +1972,7 @@ alloc_channel(struct dpaa2_eth_priv *priv) channel->dpcon = setup_dpcon(priv); if (IS_ERR_OR_NULL(channel->dpcon)) { - err = PTR_ERR(channel->dpcon); + err = PTR_ERR_OR_ZERO(channel->dpcon); goto err_setup; } @@ -2028,7 +2028,7 @@ static int setup_dpio(struct dpaa2_eth_priv *priv) /* Try to allocate a channel */ channel = alloc_channel(priv); if (IS_ERR_OR_NULL(channel)) { - err = PTR_ERR(channel); + err = PTR_ERR_OR_ZERO(channel); if (err != -EPROBE_DEFER) dev_info(dev, "No affine channel for cpu %d and above\n", i); -- cgit v1.2.3-59-g8ed1b From 4ca6dee5220fe2377bf12b354ef85978425c9ec7 Mon Sep 17 00:00:00 2001 From: Ioana Radulescu Date: Fri, 24 May 2019 18:15:17 +0300 Subject: dpaa2-eth: Make constant 64-bit long Function dpaa2_eth_cls_key_size() expects a 64bit argument, but DPAA2_ETH_DIST_ALL is defined as UINT_MAX. Fix this. Signed-off-by: Ioana Radulescu Reported-by: Dan Carpenter Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h index 5fb8f5c0dc9f..e180d5a68c98 100644 --- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h +++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h @@ -467,7 +467,7 @@ enum dpaa2_eth_rx_dist { #define DPAA2_ETH_DIST_IPPROTO BIT(6) #define DPAA2_ETH_DIST_L4SRC BIT(7) #define DPAA2_ETH_DIST_L4DST BIT(8) -#define DPAA2_ETH_DIST_ALL (~0U) +#define DPAA2_ETH_DIST_ALL (~0ULL) static inline unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv, -- cgit v1.2.3-59-g8ed1b From 3e66b7cc50ef921121babc91487e1fb98af1ba6e Mon Sep 17 00:00:00 2001 From: Kees Cook Date: Fri, 24 May 2019 13:20:19 -0700 Subject: net: tulip: de4x5: Drop redundant MODULE_DEVICE_TABLE() Building with Clang reports the redundant use of MODULE_DEVICE_TABLE(): drivers/net/ethernet/dec/tulip/de4x5.c:2110:1: error: redefinition of '__mod_eisa__de4x5_eisa_ids_device_table' MODULE_DEVICE_TABLE(eisa, de4x5_eisa_ids); ^ ./include/linux/module.h:229:21: note: expanded from macro 'MODULE_DEVICE_TABLE' extern typeof(name) __mod_##type##__##name##_device_table \ ^ :90:1: note: expanded from here __mod_eisa__de4x5_eisa_ids_device_table ^ drivers/net/ethernet/dec/tulip/de4x5.c:2100:1: note: previous definition is here MODULE_DEVICE_TABLE(eisa, de4x5_eisa_ids); ^ ./include/linux/module.h:229:21: note: expanded from macro 'MODULE_DEVICE_TABLE' extern typeof(name) __mod_##type##__##name##_device_table \ ^ :85:1: note: expanded from here __mod_eisa__de4x5_eisa_ids_device_table ^ This drops the one further from the table definition to match the common use of MODULE_DEVICE_TABLE(). Fixes: 07563c711fbc ("EISA bus MODALIAS attributes support") Signed-off-by: Kees Cook Signed-off-by: David S. Miller --- drivers/net/ethernet/dec/tulip/de4x5.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/dec/tulip/de4x5.c b/drivers/net/ethernet/dec/tulip/de4x5.c index 66535d1653f6..f16853c3c851 100644 --- a/drivers/net/ethernet/dec/tulip/de4x5.c +++ b/drivers/net/ethernet/dec/tulip/de4x5.c @@ -2107,7 +2107,6 @@ static struct eisa_driver de4x5_eisa_driver = { .remove = de4x5_eisa_remove, } }; -MODULE_DEVICE_TABLE(eisa, de4x5_eisa_ids); #endif #ifdef CONFIG_PCI -- cgit v1.2.3-59-g8ed1b From 31bafc49a7736989e4c2d9f7280002c66536e590 Mon Sep 17 00:00:00 2001 From: Igor Russkikh Date: Sat, 25 May 2019 09:57:59 +0000 Subject: net: aquantia: tx clean budget logic error In case no other traffic happening on the ring, full tx cleanup may not be completed. That may cause socket buffer to overflow and tx traffic to stuck until next activity on the ring happens. This is due to logic error in budget variable decrementor. Variable is compared with zero, and then post decremented, causing it to become MAX_INT. Solution is remove decrementor from the `for` statement and rewrite it in a clear way. Fixes: b647d3980948e ("net: aquantia: Add tx clean budget and valid budget handling logic") Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 350e385528fd..63ed00415904 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -223,10 +223,10 @@ void aq_ring_queue_stop(struct aq_ring_s *ring) bool aq_ring_tx_clean(struct aq_ring_s *self) { struct device *dev = aq_nic_get_dev(self->aq_nic); - unsigned int budget = AQ_CFG_TX_CLEAN_BUDGET; + unsigned int budget; - for (; self->sw_head != self->hw_head && budget--; - self->sw_head = aq_ring_next_dx(self, self->sw_head)) { + for (budget = AQ_CFG_TX_CLEAN_BUDGET; + budget && self->sw_head != self->hw_head; budget--) { struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; if (likely(buff->is_mapped)) { @@ -251,6 +251,7 @@ bool aq_ring_tx_clean(struct aq_ring_s *self) buff->pa = 0U; buff->eop_index = 0xffffU; + self->sw_head = aq_ring_next_dx(self, self->sw_head); } return !!budget; -- cgit v1.2.3-59-g8ed1b From f38f1ee8aeb2c19f65fc29de49bed231a868198c Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Sat, 25 May 2019 09:58:01 +0000 Subject: net: aquantia: check rx csum for all packets in LRO session Atlantic hardware does not aggregate nor breaks LRO sessions with bad csum packets. This means driver should take care of that. If in LRO session there is a non-first descriptor with invalid checksum (L2/L3/L4), the driver must account this information in csum application logic. Fixes: 018423e90bee8 ("net: ethernet: aquantia: Add ring support code") Signed-off-by: Igor Russkikh Signed-off-by: Dmitry Bogdanov Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/aq_ring.c | 44 +++++++++++++++++------- 1 file changed, 31 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 63ed00415904..941b0beb87ef 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -299,35 +299,47 @@ int aq_ring_rx_clean(struct aq_ring_s *self, unsigned int i = 0U; u16 hdr_len; - if (buff->is_error) - continue; - if (buff->is_cleaned) continue; if (!buff->is_eop) { - for (next_ = buff->next, - buff_ = &self->buff_ring[next_]; true; - next_ = buff_->next, - buff_ = &self->buff_ring[next_]) { + buff_ = buff; + do { + next_ = buff_->next, + buff_ = &self->buff_ring[next_]; is_rsc_completed = aq_ring_dx_in_range(self->sw_head, next_, self->hw_head); - if (unlikely(!is_rsc_completed)) { - is_rsc_completed = false; + if (unlikely(!is_rsc_completed)) break; - } - if (buff_->is_eop) - break; - } + buff->is_error |= buff_->is_error; + + } while (!buff_->is_eop); if (!is_rsc_completed) { err = 0; goto err_exit; } + if (buff->is_error) { + buff_ = buff; + do { + next_ = buff_->next, + buff_ = &self->buff_ring[next_]; + + buff_->is_cleaned = true; + } while (!buff_->is_eop); + + ++self->stats.rx.errors; + continue; + } + } + + if (buff->is_error) { + ++self->stats.rx.errors; + continue; } dma_sync_single_range_for_cpu(aq_nic_get_dev(self->aq_nic), @@ -390,6 +402,12 @@ int aq_ring_rx_clean(struct aq_ring_s *self, AQ_CFG_RX_FRAME_MAX); page_ref_inc(buff_->rxdata.page); buff_->is_cleaned = 1; + + buff->is_ip_cso &= buff_->is_ip_cso; + buff->is_udp_cso &= buff_->is_udp_cso; + buff->is_tcp_cso &= buff_->is_tcp_cso; + buff->is_cso_err |= buff_->is_cso_err; + } while (!buff_->is_eop); } } -- cgit v1.2.3-59-g8ed1b From eaeb3b7494ba9159323814a8ce8af06a9277d99b Mon Sep 17 00:00:00 2001 From: Dmitry Bogdanov Date: Sat, 25 May 2019 09:58:03 +0000 Subject: net: aquantia: fix LRO with FCS error Driver stops producing skbs on ring if a packet with FCS error was coalesced into LRO session. Ring gets hang forever. Thats a logical error in driver processing descriptors: When rx_stat indicates MAC Error, next pointer and eop flags are not filled. This confuses driver so it waits for descriptor 0 to be filled by HW. Solution is fill next pointer and eop flag even for packets with FCS error. Fixes: bab6de8fd180b ("net: ethernet: aquantia: Atlantic A0 and B0 specific functions.") Signed-off-by: Igor Russkikh Signed-off-by: Dmitry Bogdanov Signed-off-by: David S. Miller --- .../ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 61 ++++++++++++---------- 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index bfcda12d73de..e979f227cf0b 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -713,38 +713,41 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self, if ((rx_stat & BIT(0)) || rxd_wb->type & 0x1000U) { /* MAC error or DMA error */ buff->is_error = 1U; - } else { - if (self->aq_nic_cfg->is_rss) { - /* last 4 byte */ - u16 rss_type = rxd_wb->type & 0xFU; - - if (rss_type && rss_type < 0x8U) { - buff->is_hash_l4 = (rss_type == 0x4 || - rss_type == 0x5); - buff->rss_hash = rxd_wb->rss_hash; - } + } + if (self->aq_nic_cfg->is_rss) { + /* last 4 byte */ + u16 rss_type = rxd_wb->type & 0xFU; + + if (rss_type && rss_type < 0x8U) { + buff->is_hash_l4 = (rss_type == 0x4 || + rss_type == 0x5); + buff->rss_hash = rxd_wb->rss_hash; } + } - if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) { - buff->len = rxd_wb->pkt_len % - AQ_CFG_RX_FRAME_MAX; - buff->len = buff->len ? - buff->len : AQ_CFG_RX_FRAME_MAX; - buff->next = 0U; - buff->is_eop = 1U; + if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) { + buff->len = rxd_wb->pkt_len % + AQ_CFG_RX_FRAME_MAX; + buff->len = buff->len ? + buff->len : AQ_CFG_RX_FRAME_MAX; + buff->next = 0U; + buff->is_eop = 1U; + } else { + buff->len = + rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ? + AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len; + + if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT & + rxd_wb->status) { + /* LRO */ + buff->next = rxd_wb->next_desc_ptr; + ++ring->stats.rx.lro_packets; } else { - if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT & - rxd_wb->status) { - /* LRO */ - buff->next = rxd_wb->next_desc_ptr; - ++ring->stats.rx.lro_packets; - } else { - /* jumbo */ - buff->next = - aq_ring_next_dx(ring, - ring->hw_head); - ++ring->stats.rx.jumbo_packets; - } + /* jumbo */ + buff->next = + aq_ring_next_dx(ring, + ring->hw_head); + ++ring->stats.rx.jumbo_packets; } } } -- cgit v1.2.3-59-g8ed1b From 76f254d4afe2f9c5860922d5304821b4ef05b712 Mon Sep 17 00:00:00 2001 From: Nikita Danilov Date: Sat, 25 May 2019 09:58:05 +0000 Subject: net: aquantia: tcp checksum 0xffff being handled incorrectly Thats a known quirk in windows tcp stack it can produce 0xffff checksum. Thats incorrect but it is. Atlantic HW with LRO enabled handles that incorrectly and changes csum to 0xfffe - but indicates that csum is invalid. This causes driver to pass packet to linux networking stack with CSUM_NONE, stack eventually drops the packet. There is a quirk in atlantic HW to enable correct processing of 0xffff incorrect csum. Enable it. The visible bug is that windows link partner with software generated csums caused TCP connection to be unstable since all packets that csum value are dropped. Reported-by: Dmitry Bezrukov Signed-off-by: Nikita Danilov Signed-off-by: Igor Russkikh Signed-off-by: David S. Miller --- drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index e979f227cf0b..5c3065bdfddf 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c @@ -266,12 +266,11 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self, */ hw_atl_rpo_lro_max_coalescing_interval_set(self, 50); - hw_atl_rpo_lro_qsessions_lim_set(self, 1U); hw_atl_rpo_lro_total_desc_lim_set(self, 2U); - hw_atl_rpo_lro_patch_optimization_en_set(self, 0U); + hw_atl_rpo_lro_patch_optimization_en_set(self, 1U); hw_atl_rpo_lro_min_pay_of_first_pkt_set(self, 10U); -- cgit v1.2.3-59-g8ed1b From 54ed6fd2e03fd38819afa60a5b4cb61874230d34 Mon Sep 17 00:00:00 2001 From: Thierry Reding Date: Mon, 27 May 2019 12:52:51 +0200 Subject: net: stmmac: Do not output error on deferred probe If the subdriver defers probe, do not show an error message. It's perfectly fine for this error to occur since the driver will get another chance to probe after some time and will usually succeed after all of the resources that it requires have been registered. Signed-off-by: Thierry Reding Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c index 3256e5cbad27..5bc224834c77 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-dwc-qos-eth.c @@ -455,7 +455,11 @@ static int dwc_eth_dwmac_probe(struct platform_device *pdev) priv = data->probe(pdev, plat_dat, &stmmac_res); if (IS_ERR(priv)) { ret = PTR_ERR(priv); - dev_err(&pdev->dev, "failed to probe subdriver: %d\n", ret); + + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "failed to probe subdriver: %d\n", + ret); + goto remove_config; } -- cgit v1.2.3-59-g8ed1b From d484e06e25ebb937d841dac02ac1fe76ec7d4ddd Mon Sep 17 00:00:00 2001 From: Jisheng Zhang Date: Mon, 27 May 2019 11:04:17 +0000 Subject: net: mvneta: Fix err code path of probe Fix below issues in err code path of probe: 1. we don't need to unregister_netdev() because the netdev isn't registered. 2. when register_netdev() fails, we also need to destroy bm pool for HWBM case. Fixes: dc35a10f68d3 ("net: mvneta: bm: add support for hardware buffer management") Signed-off-by: Jisheng Zhang Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvneta.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index e758650b2c26..269bd73be1a0 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -4674,7 +4674,7 @@ static int mvneta_probe(struct platform_device *pdev) err = register_netdev(dev); if (err < 0) { dev_err(&pdev->dev, "failed to register\n"); - goto err_free_stats; + goto err_netdev; } netdev_info(dev, "Using %s mac address %pM\n", mac_from, @@ -4685,14 +4685,12 @@ static int mvneta_probe(struct platform_device *pdev) return 0; err_netdev: - unregister_netdev(dev); if (pp->bm_priv) { mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_long, 1 << pp->id); mvneta_bm_pool_destroy(pp->bm_priv, pp->pool_short, 1 << pp->id); mvneta_bm_put(pp->bm_priv); } -err_free_stats: free_percpu(pp->stats); err_free_ports: free_percpu(pp->ports); -- cgit v1.2.3-59-g8ed1b From 7aae703f8096d21e34ce5f34f16715587bc30902 Mon Sep 17 00:00:00 2001 From: Madalin Bucur Date: Mon, 27 May 2019 15:24:05 +0300 Subject: dpaa_eth: use only online CPU portals Make sure only the portals for the online CPUs are used. Without this change, there are issues when someone boots with maxcpus=n, with n < actual number of cores available as frames either received or corresponding to the transmit confirmation path would be offered for dequeue to the offline CPU portals, getting lost. Signed-off-by: Madalin Bucur Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/dpaa/dpaa_eth.c | 9 ++++----- drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c index d3f2408dc9e8..f38c3fa7d705 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_eth.c @@ -780,7 +780,7 @@ static void dpaa_eth_add_channel(u16 channel) struct qman_portal *portal; int cpu; - for_each_cpu(cpu, cpus) { + for_each_cpu_and(cpu, cpus, cpu_online_mask) { portal = qman_get_affine_portal(cpu); qman_p_static_dequeue_add(portal, pool); } @@ -896,7 +896,7 @@ static void dpaa_fq_setup(struct dpaa_priv *priv, u16 channels[NR_CPUS]; struct dpaa_fq *fq; - for_each_cpu(cpu, affine_cpus) + for_each_cpu_and(cpu, affine_cpus, cpu_online_mask) channels[num_portals++] = qman_affine_channel(cpu); if (num_portals == 0) @@ -2174,7 +2174,6 @@ static int dpaa_eth_poll(struct napi_struct *napi, int budget) if (cleaned < budget) { napi_complete_done(napi, cleaned); qman_p_irqsource_add(np->p, QM_PIRQ_DQRI); - } else if (np->down) { qman_p_irqsource_add(np->p, QM_PIRQ_DQRI); } @@ -2448,7 +2447,7 @@ static void dpaa_eth_napi_enable(struct dpaa_priv *priv) struct dpaa_percpu_priv *percpu_priv; int i; - for_each_possible_cpu(i) { + for_each_online_cpu(i) { percpu_priv = per_cpu_ptr(priv->percpu_priv, i); percpu_priv->np.down = 0; @@ -2461,7 +2460,7 @@ static void dpaa_eth_napi_disable(struct dpaa_priv *priv) struct dpaa_percpu_priv *percpu_priv; int i; - for_each_possible_cpu(i) { + for_each_online_cpu(i) { percpu_priv = per_cpu_ptr(priv->percpu_priv, i); percpu_priv->np.down = 1; diff --git a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c index bdee441bc3b7..7ce2e99b594d 100644 --- a/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c +++ b/drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c @@ -569,7 +569,7 @@ static int dpaa_set_coalesce(struct net_device *dev, qman_dqrr_get_ithresh(portal, &prev_thresh); /* set new values */ - for_each_cpu(cpu, cpus) { + for_each_cpu_and(cpu, cpus, cpu_online_mask) { portal = qman_get_affine_portal(cpu); res = qman_portal_set_iperiod(portal, period); if (res) @@ -586,7 +586,7 @@ static int dpaa_set_coalesce(struct net_device *dev, revert_values: /* restore previous values */ - for_each_cpu(cpu, cpus) { + for_each_cpu_and(cpu, cpus, cpu_online_mask) { if (!needs_revert[cpu]) continue; portal = qman_get_affine_portal(cpu); -- cgit v1.2.3-59-g8ed1b From 8788392995e7f1ea87d4efa03c14d872b05f9f25 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Thu, 16 May 2019 11:11:11 -0700 Subject: net/mlx5: Fix error handling in mlx5_load() In case mlx5_core_set_hca_defaults fails, it should jump to mlx5_cleanup_fs, fix that. Fixes: c85023e153e3 ("IB/mlx5: Add raw ethernet local loopback support") Signed-off-by: Saeed Mahameed Reviewed-by: Huy Nguyen Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 61fa1d162d28..23d53163ce15 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1067,7 +1067,7 @@ static int mlx5_load(struct mlx5_core_dev *dev) err = mlx5_core_set_hca_defaults(dev); if (err) { mlx5_core_err(dev, "Failed to set hca defaults\n"); - goto err_fs; + goto err_sriov; } err = mlx5_sriov_attach(dev); -- cgit v1.2.3-59-g8ed1b From 905f6bd30bb6c244f97cdf5fb5d55cf263844490 Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Thu, 9 May 2019 17:23:24 -0500 Subject: net/mlx5: Avoid double free of root ns in the error flow path When root ns setup for rdma, sniffer tx and sniffer rx fails, such root ns cleanup is done by the error unwinding path of mlx5_cleanup_fs(). Below call graph shows an example for sniffer_rx_root_ns. mlx5_init_fs() init_sniffer_rx_root_ns() cleanup_root_ns(steering->sniffer_rx_root_ns); mlx5_cleanup_fs() cleanup_root_ns(steering->sniffer_rx_root_ns); /* double free of sniffer_rx_root_ns */ Hence, use the existing cleanup_fs to cleanup. Fixes: d83eb50e29de3 ("net/mlx5: Add support in RDMA RX steering") Fixes: 87d22483ce68e ("net/mlx5: Add sniffer namespaces") Signed-off-by: Parav Pandit Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index d7ca7e82a832..4fa87ca63bca 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -2474,11 +2474,7 @@ static int init_sniffer_tx_root_ns(struct mlx5_flow_steering *steering) /* Create single prio */ prio = fs_create_prio(&steering->sniffer_tx_root_ns->ns, 0, 1); - if (IS_ERR(prio)) { - cleanup_root_ns(steering->sniffer_tx_root_ns); - return PTR_ERR(prio); - } - return 0; + return PTR_ERR_OR_ZERO(prio); } static int init_sniffer_rx_root_ns(struct mlx5_flow_steering *steering) @@ -2491,11 +2487,7 @@ static int init_sniffer_rx_root_ns(struct mlx5_flow_steering *steering) /* Create single prio */ prio = fs_create_prio(&steering->sniffer_rx_root_ns->ns, 0, 1); - if (IS_ERR(prio)) { - cleanup_root_ns(steering->sniffer_rx_root_ns); - return PTR_ERR(prio); - } - return 0; + return PTR_ERR_OR_ZERO(prio); } static int init_rdma_rx_root_ns(struct mlx5_flow_steering *steering) @@ -2511,11 +2503,7 @@ static int init_rdma_rx_root_ns(struct mlx5_flow_steering *steering) /* Create single prio */ prio = fs_create_prio(&steering->rdma_rx_root_ns->ns, 0, 1); - if (IS_ERR(prio)) { - cleanup_root_ns(steering->rdma_rx_root_ns); - return PTR_ERR(prio); - } - return 0; + return PTR_ERR_OR_ZERO(prio); } static int init_fdb_root_ns(struct mlx5_flow_steering *steering) { -- cgit v1.2.3-59-g8ed1b From 9414277a5df3669c67e818708c0f881597e0118e Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Fri, 10 May 2019 10:26:23 -0500 Subject: net/mlx5: Avoid double free in fs init error unwinding path In below code flow, for ingress acl table root ns memory leads to double free. mlx5_init_fs init_ingress_acls_root_ns() init_ingress_acl_root_ns kfree(steering->esw_ingress_root_ns); /* steering->esw_ingress_root_ns is not marked NULL */ mlx5_cleanup_fs cleanup_ingress_acls_root_ns steering->esw_ingress_root_ns non NULL check passes. kfree(steering->esw_ingress_root_ns); /* double free */ Similar issue exist for other tables. Hence zero out the pointers to not process the table again. Fixes: 9b93ab981e3bf ("net/mlx5: Separate ingress/egress namespaces for each vport") Fixes: 40c3eebb49e51 ("net/mlx5: Add support in RDMA RX steering") Signed-off-by: Parav Pandit Reviewed-by: Mark Bloch Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 4fa87ca63bca..34276a2b6da2 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -2427,6 +2427,7 @@ static void cleanup_egress_acls_root_ns(struct mlx5_core_dev *dev) cleanup_root_ns(steering->esw_egress_root_ns[i]); kfree(steering->esw_egress_root_ns); + steering->esw_egress_root_ns = NULL; } static void cleanup_ingress_acls_root_ns(struct mlx5_core_dev *dev) @@ -2441,6 +2442,7 @@ static void cleanup_ingress_acls_root_ns(struct mlx5_core_dev *dev) cleanup_root_ns(steering->esw_ingress_root_ns[i]); kfree(steering->esw_ingress_root_ns); + steering->esw_ingress_root_ns = NULL; } void mlx5_cleanup_fs(struct mlx5_core_dev *dev) @@ -2625,6 +2627,7 @@ cleanup_root_ns: for (i--; i >= 0; i--) cleanup_root_ns(steering->esw_egress_root_ns[i]); kfree(steering->esw_egress_root_ns); + steering->esw_egress_root_ns = NULL; return err; } @@ -2652,6 +2655,7 @@ cleanup_root_ns: for (i--; i >= 0; i--) cleanup_root_ns(steering->esw_ingress_root_ns[i]); kfree(steering->esw_ingress_root_ns); + steering->esw_ingress_root_ns = NULL; return err; } -- cgit v1.2.3-59-g8ed1b From 25fa506b70cadb580c1e9cbd836d6417276d4bcd Mon Sep 17 00:00:00 2001 From: Parav Pandit Date: Fri, 10 May 2019 10:40:08 -0500 Subject: net/mlx5: Allocate root ns memory using kzalloc to match kfree root ns is yet another fs core node which is freed using kfree() by tree_put_node(). Rest of the other fs core objects are also allocated using kmalloc variants. However, root ns memory is allocated using kvzalloc(). Hence allocate root ns memory using kzalloc(). Fixes: 2530236303d9e ("net/mlx5_core: Flow steering tree initialization") Signed-off-by: Parav Pandit Reviewed-by: Daniel Jurgens Reviewed-by: Mark Bloch Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/fs_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index 34276a2b6da2..fe76c6fd6d80 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c @@ -2284,7 +2284,7 @@ static struct mlx5_flow_root_namespace cmds = mlx5_fs_cmd_get_default_ipsec_fpga_cmds(table_type); /* Create the root namespace */ - root_ns = kvzalloc(sizeof(*root_ns), GFP_KERNEL); + root_ns = kzalloc(sizeof(*root_ns), GFP_KERNEL); if (!root_ns) return NULL; -- cgit v1.2.3-59-g8ed1b From 24bcd210e272c1e5fc712fbc5e5c21f59a21abf7 Mon Sep 17 00:00:00 2001 From: wenxu Date: Wed, 15 May 2019 17:25:45 +0800 Subject: net/mlx5e: restrict the real_dev of vlan device is the same as uplink device When register indr block for vlan device, it should check the real_dev of vlan device is same as uplink device. Or it will set offload rule to mlx5e which will never hit. Fixes: 35a605db168c ("net/mlx5e: Offload TC e-switch rules with ingress VLAN device") Signed-off-by: wenxu Reviewed-by: Roi Dayan Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_rep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c index 5283e16c69e4..9aea9c5b2ce8 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c @@ -813,7 +813,7 @@ static int mlx5e_nic_rep_netdevice_event(struct notifier_block *nb, struct net_device *netdev = netdev_notifier_info_to_dev(ptr); if (!mlx5e_tc_tun_device_to_offload(priv, netdev) && - !is_vlan_dev(netdev)) + !(is_vlan_dev(netdev) && vlan_dev_real_dev(netdev) == rpriv->netdev)) return NOTIFY_OK; switch (event) { -- cgit v1.2.3-59-g8ed1b From c0194e2d0ef0e5ce5e21a35640d23a706827ae28 Mon Sep 17 00:00:00 2001 From: Saeed Mahameed Date: Thu, 23 May 2019 12:55:10 -0700 Subject: net/mlx5e: Disable rxhash when CQE compress is enabled When CQE compression is enabled (Multi-host systems), compressed CQEs might arrive to the driver rx, compressed CQEs don't have a valid hash offload and the driver already reports a hash value of 0 and invalid hash type on the skb for compressed CQEs, but this is not good enough. On a congested PCIe, where CQE compression will kick in aggressively, gro will deliver lots of out of order packets due to the invalid hash and this might cause a serious performance drop. The only valid solution, is to disable rxhash offload at all when CQE compression is favorable (Multi-host systems). Fixes: 7219ab34f184 ("net/mlx5e: CQE compression") Signed-off-by: Saeed Mahameed --- drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 457cc39423f2..c65cefd84eda 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -3687,6 +3687,12 @@ static netdev_features_t mlx5e_fix_features(struct net_device *netdev, netdev_warn(netdev, "Disabling LRO, not supported in legacy RQ\n"); } + if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)) { + features &= ~NETIF_F_RXHASH; + if (netdev->features & NETIF_F_RXHASH) + netdev_warn(netdev, "Disabling rxhash, not supported when CQE compress is active\n"); + } + mutex_unlock(&priv->state_lock); return features; @@ -3812,6 +3818,9 @@ int mlx5e_hwstamp_set(struct mlx5e_priv *priv, struct ifreq *ifr) memcpy(&priv->tstamp, &config, sizeof(config)); mutex_unlock(&priv->state_lock); + /* might need to fix some features */ + netdev_update_features(priv->netdev); + return copy_to_user(ifr->ifr_data, &config, sizeof(config)) ? -EFAULT : 0; } @@ -4680,6 +4689,10 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) if (!priv->channels.params.scatter_fcs_en) netdev->features &= ~NETIF_F_RXFCS; + /* prefere CQE compression over rxhash */ + if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS)) + netdev->features &= ~NETIF_F_RXHASH; + #define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f) if (FT_CAP(flow_modify_en) && FT_CAP(modify_root) && -- cgit v1.2.3-59-g8ed1b From 315ca92dd863fecbffc0bb52ae0ac11e0398726a Mon Sep 17 00:00:00 2001 From: Yoshihiro Shimoda Date: Tue, 28 May 2019 13:10:46 +0900 Subject: net: sh_eth: fix mdio access in sh_eth_close() for R-Car Gen2 and RZ/A1 SoCs The sh_eth_close() resets the MAC and then calls phy_stop() so that mdio read access result is incorrect without any error according to kernel trace like below: ifconfig-216 [003] .n.. 109.133124: mdio_access: ee700000.ethernet-ffffffff read phy:0x01 reg:0x00 val:0xffff According to the hardware manual, the RMII mode should be set to 1 before operation the Ethernet MAC. However, the previous code was not set to 1 after the driver issued the soft_reset in sh_eth_dev_exit() so that the mdio read access result seemed incorrect. To fix the issue, this patch adds a condition and set the RMII mode register in sh_eth_dev_exit() for R-Car Gen2 and RZ/A1 SoCs. Note that when I have tried to move the sh_eth_dev_exit() calling after phy_stop() on sh_eth_close(), but it gets worse (kernel panic happened and it seems that a register is accessed while the clock is off). Signed-off-by: Yoshihiro Shimoda Signed-off-by: David S. Miller --- drivers/net/ethernet/renesas/sh_eth.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index 6354f19a31eb..7ba35a0bdb29 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c @@ -1594,6 +1594,10 @@ static void sh_eth_dev_exit(struct net_device *ndev) sh_eth_get_stats(ndev); mdp->cd->soft_reset(ndev); + /* Set the RMII mode again if required */ + if (mdp->cd->rmiimode) + sh_eth_write(ndev, 0x1, RMIIMODE); + /* Set MAC address again */ update_mac_address(ndev); } -- cgit v1.2.3-59-g8ed1b From c678726305b9425454be7c8a7624290b602602fc Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 May 2019 10:27:21 +0100 Subject: net: phylink: ensure consistent phy interface mode Ensure that we supply the same phy interface mode to mac_link_down() as we did for the corresponding mac_link_up() call. This ensures that MAC drivers that use the phy interface mode in these methods can depend on mac_link_down() always corresponding to a mac_link_up() call for the same interface mode. Signed-off-by: Russell King Signed-off-by: David S. Miller --- drivers/net/phy/phylink.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 74983593834b..9044b95d2afe 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c @@ -51,6 +51,10 @@ struct phylink { /* The link configuration settings */ struct phylink_link_state link_config; + + /* The current settings */ + phy_interface_t cur_interface; + struct gpio_desc *link_gpio; struct timer_list link_poll; void (*get_fixed_state)(struct net_device *dev, @@ -446,12 +450,12 @@ static void phylink_resolve(struct work_struct *w) if (!link_state.link) { netif_carrier_off(ndev); pl->ops->mac_link_down(ndev, pl->link_an_mode, - pl->phy_state.interface); + pl->cur_interface); netdev_info(ndev, "Link is Down\n"); } else { + pl->cur_interface = link_state.interface; pl->ops->mac_link_up(ndev, pl->link_an_mode, - pl->phy_state.interface, - pl->phydev); + pl->cur_interface, pl->phydev); netif_carrier_on(ndev); -- cgit v1.2.3-59-g8ed1b From 3d3ced2ec5d71b99d72ae6910fbdf890bc2eccf0 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 28 May 2019 10:34:42 +0100 Subject: net: phy: marvell10g: report if the PHY fails to boot firmware Some boards do not have the PHY firmware programmed in the 3310's flash, which leads to the PHY not working as expected. Warn the user when the PHY fails to boot the firmware and refuse to initialise. Fixes: 20b2af32ff3f ("net: phy: add Marvell Alaska X 88X3310 10Gigabit PHY support") Signed-off-by: Russell King Tested-by: Maxime Chevallier Reviewed-by: Andrew Lunn Signed-off-by: David S. Miller --- drivers/net/phy/marvell10g.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/marvell10g.c b/drivers/net/phy/marvell10g.c index 238a20e13d6a..3b99882692e3 100644 --- a/drivers/net/phy/marvell10g.c +++ b/drivers/net/phy/marvell10g.c @@ -31,6 +31,9 @@ #define MV_PHY_ALASKA_NBT_QUIRK_REV (MARVELL_PHY_ID_88X3310 | 0xa) enum { + MV_PMA_BOOT = 0xc050, + MV_PMA_BOOT_FATAL = BIT(0), + MV_PCS_BASE_T = 0x0000, MV_PCS_BASE_R = 0x1000, MV_PCS_1000BASEX = 0x2000, @@ -213,6 +216,16 @@ static int mv3310_probe(struct phy_device *phydev) (phydev->c45_ids.devices_in_package & mmd_mask) != mmd_mask) return -ENODEV; + ret = phy_read_mmd(phydev, MDIO_MMD_PMAPMD, MV_PMA_BOOT); + if (ret < 0) + return ret; + + if (ret & MV_PMA_BOOT_FATAL) { + dev_warn(&phydev->mdio.dev, + "PHY failed to boot firmware, status=%04x\n", ret); + return -ENODEV; + } + priv = devm_kzalloc(&phydev->mdio.dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; -- cgit v1.2.3-59-g8ed1b From 333061b924539c0de081339643f45514f5f1c1e6 Mon Sep 17 00:00:00 2001 From: Max Uvarov Date: Tue, 28 May 2019 13:00:49 +0300 Subject: net: phy: dp83867: fix speed 10 in sgmii mode For supporting 10Mps speed in SGMII mode DP83867_10M_SGMII_RATE_ADAPT bit of DP83867_10M_SGMII_CFG register has to be cleared by software. That does not affect speeds 100 and 1000 so can be done on init. Signed-off-by: Max Uvarov Cc: Heiner Kallweit Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/dp83867.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index fd35131a0c39..1091a625bf4c 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -30,6 +30,8 @@ #define DP83867_STRAP_STS1 0x006E #define DP83867_RGMIIDCTL 0x0086 #define DP83867_IO_MUX_CFG 0x0170 +#define DP83867_10M_SGMII_CFG 0x016F +#define DP83867_10M_SGMII_RATE_ADAPT_MASK BIT(7) #define DP83867_SW_RESET BIT(15) #define DP83867_SW_RESTART BIT(14) @@ -277,6 +279,21 @@ static int dp83867_config_init(struct phy_device *phydev) DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL); } + if (phydev->interface == PHY_INTERFACE_MODE_SGMII) { + /* For support SPEED_10 in SGMII mode + * DP83867_10M_SGMII_RATE_ADAPT bit + * has to be cleared by software. That + * does not affect SPEED_100 and + * SPEED_1000. + */ + ret = phy_modify_mmd(phydev, DP83867_DEVADDR, + DP83867_10M_SGMII_CFG, + DP83867_10M_SGMII_RATE_ADAPT_MASK, + 0); + if (ret) + return ret; + } + /* Enable Interrupt output INT_OE in CFG3 register */ if (phy_interrupt_is_valid(phydev)) { val = phy_read(phydev, DP83867_CFG3); -- cgit v1.2.3-59-g8ed1b From 1a97a477e666cbdededab93bd3754e508f0c09d7 Mon Sep 17 00:00:00 2001 From: Max Uvarov Date: Tue, 28 May 2019 13:00:50 +0300 Subject: net: phy: dp83867: increase SGMII autoneg timer duration After reset SGMII Autoneg timer is set to 2us (bits 6 and 5 are 01). That is not enough to finalize autonegatiation on some devices. Increase this timer duration to maximum supported 16ms. Signed-off-by: Max Uvarov Cc: Heiner Kallweit Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/dp83867.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 1091a625bf4c..14e9e8a94639 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -26,6 +26,12 @@ /* Extended Registers */ #define DP83867_CFG4 0x0031 +#define DP83867_CFG4_SGMII_ANEG_MASK (BIT(5) | BIT(6)) +#define DP83867_CFG4_SGMII_ANEG_TIMER_11MS (3 << 5) +#define DP83867_CFG4_SGMII_ANEG_TIMER_800US (2 << 5) +#define DP83867_CFG4_SGMII_ANEG_TIMER_2US (1 << 5) +#define DP83867_CFG4_SGMII_ANEG_TIMER_16MS (0 << 5) + #define DP83867_RGMIICTL 0x0032 #define DP83867_STRAP_STS1 0x006E #define DP83867_RGMIIDCTL 0x0086 @@ -292,6 +298,18 @@ static int dp83867_config_init(struct phy_device *phydev) 0); if (ret) return ret; + + /* After reset SGMII Autoneg timer is set to 2us (bits 6 and 5 + * are 01). That is not enough to finalize autoneg on some + * devices. Increase this timer duration to maximum 16ms. + */ + ret = phy_modify_mmd(phydev, DP83867_DEVADDR, + DP83867_CFG4, + DP83867_CFG4_SGMII_ANEG_MASK, + DP83867_CFG4_SGMII_ANEG_TIMER_16MS); + + if (ret) + return ret; } /* Enable Interrupt output INT_OE in CFG3 register */ -- cgit v1.2.3-59-g8ed1b From c8081fc397fa04675e410900693a57085ef4b760 Mon Sep 17 00:00:00 2001 From: Max Uvarov Date: Tue, 28 May 2019 13:00:51 +0300 Subject: net: phy: dp83867: do not call config_init twice Phy state machine calls _config_init just after reset. Signed-off-by: Max Uvarov Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/dp83867.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 14e9e8a94639..1ec48ecf4133 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -342,7 +342,7 @@ static int dp83867_phy_reset(struct phy_device *phydev) usleep_range(10, 20); - return dp83867_config_init(phydev); + return 0; } static struct phy_driver dp83867_driver[] = { -- cgit v1.2.3-59-g8ed1b From 2b892649254fec01678c64f16427622b41fa27f4 Mon Sep 17 00:00:00 2001 From: Max Uvarov Date: Tue, 28 May 2019 13:00:52 +0300 Subject: net: phy: dp83867: Set up RGMII TX delay PHY_INTERFACE_MODE_RGMII_RXID is less then TXID so code to set tx delay is never called. Fixes: 2a10154abcb75 ("net: phy: dp83867: Add TI dp83867 phy") Signed-off-by: Max Uvarov Cc: Florian Fainelli Reviewed-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/phy/dp83867.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index 1ec48ecf4133..c71c7d0f53f0 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -255,10 +255,8 @@ static int dp83867_config_init(struct phy_device *phydev) ret = phy_write(phydev, MII_DP83867_PHYCTRL, val); if (ret) return ret; - } - if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) && - (phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) { + /* Set up RGMII delays */ val = phy_read_mmd(phydev, DP83867_DEVADDR, DP83867_RGMIICTL); if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) -- cgit v1.2.3-59-g8ed1b From 996ed04741467f6d1552440c92988b132a9487ec Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 28 May 2019 11:47:30 -0700 Subject: netvsc: unshare skb in VF rx handler The netvsc VF skb handler should make sure that skb is not shared. Similar logic already exists in bonding and team device drivers. This is not an issue in practice because the VF devicex does not send up shared skb's. But the netvsc driver should do the right thing if it did. Fixes: 0c195567a8f6 ("netvsc: transparent VF management") Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/hyperv/netvsc_drv.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 06393b215102..9873b8679f81 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c @@ -2000,6 +2000,12 @@ static rx_handler_result_t netvsc_vf_handle_frame(struct sk_buff **pskb) struct netvsc_vf_pcpu_stats *pcpu_stats = this_cpu_ptr(ndev_ctx->vf_stats); + skb = skb_share_check(skb, GFP_ATOMIC); + if (unlikely(!skb)) + return RX_HANDLER_CONSUMED; + + *pskb = skb; + skb->dev = ndev; u64_stats_update_begin(&pcpu_stats->syncp); -- cgit v1.2.3-59-g8ed1b From 59715171fbd0172a579576f46821031800a63bc5 Mon Sep 17 00:00:00 2001 From: Heiner Kallweit Date: Wed, 29 May 2019 07:44:01 +0200 Subject: r8169: fix MAC address being lost in PCI D3 (At least) RTL8168e forgets its MAC address in PCI D3. To fix this set the MAC address when resuming. For resuming from runtime-suspend we had this in place already, for resuming from S3/S5 it was missing. The commit referenced as being fixed isn't wrong, it's just the first one where the patch applies cleanly. Fixes: 0f07bd850d36 ("r8169: use dev_get_drvdata where possible") Signed-off-by: Heiner Kallweit Reported-by: Albert Astals Cid Tested-by: Albert Astals Cid Signed-off-by: David S. Miller --- drivers/net/ethernet/realtek/r8169.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 8e404186ef87..d06a61f00e78 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -6722,6 +6722,8 @@ static int rtl8169_resume(struct device *device) struct net_device *dev = dev_get_drvdata(device); struct rtl8169_private *tp = netdev_priv(dev); + rtl_rar_set(tp, dev->dev_addr); + clk_prepare_enable(tp->clk); if (netif_running(dev)) @@ -6755,6 +6757,7 @@ static int rtl8169_runtime_resume(struct device *device) { struct net_device *dev = dev_get_drvdata(device); struct rtl8169_private *tp = netdev_priv(dev); + rtl_rar_set(tp, dev->dev_addr); if (!tp->TxDescArray) -- cgit v1.2.3-59-g8ed1b From 84b3fd1fc9592d431e23b077e692fa4e3fd0f086 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 29 May 2019 07:02:11 +0000 Subject: net: dsa: mv88e6xxx: fix handling of upper half of STATS_TYPE_PORT Currently, the upper half of a 4-byte STATS_TYPE_PORT statistic ends up in bits 47:32 of the return value, instead of bits 31:16 as they should. Fixes: 6e46e2d821bb ("net: dsa: mv88e6xxx: Fix u64 statistics") Signed-off-by: Rasmus Villemoes Reviewed-by: Vivien Didelot Signed-off-by: David S. Miller --- drivers/net/dsa/mv88e6xxx/chip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 28414db979b0..12f165a71a6c 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c @@ -785,7 +785,7 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip, err = mv88e6xxx_port_read(chip, port, s->reg + 1, ®); if (err) return U64_MAX; - high = reg; + low |= ((u32)reg) << 16; } break; case STATS_TYPE_BANK1: -- cgit v1.2.3-59-g8ed1b From ef74422020aa8c224b00a927e3e47faac4d8fae3 Mon Sep 17 00:00:00 2001 From: Jiri Pirko Date: Wed, 29 May 2019 10:59:44 +0300 Subject: mlxsw: spectrum_acl: Avoid warning after identical rules insertion When identical rules are inserted, the latter one goes to C-TCAM. For that, a second eRP with the same mask is created. These 2 eRPs by the nature cannot be merged and also one cannot be parent of another. Teach mlxsw_sp_acl_erp_delta_fill() about this possibility and handle it gracefully. Reported-by: Alex Kushnarov Fixes: c22291f7cf45 ("mlxsw: spectrum: acl: Implement delta for ERP") Signed-off-by: Jiri Pirko Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c index c1a9cc9a3292..4c98950380d5 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_acl_erp.c @@ -1171,13 +1171,12 @@ mlxsw_sp_acl_erp_delta_fill(const struct mlxsw_sp_acl_erp_key *parent_key, return -EINVAL; } if (si == -1) { - /* The masks are the same, this cannot happen. - * That means the caller is broken. + /* The masks are the same, this can happen in case eRPs with + * the same mask were created in both A-TCAM and C-TCAM. + * The only possible condition under which this can happen + * is identical rule insertion. Delta is not possible here. */ - WARN_ON(1); - *delta_start = 0; - *delta_mask = 0; - return 0; + return -EINVAL; } pmask = (unsigned char) parent_key->mask[__MASK_IDX(si)]; mask = (unsigned char) key->mask[__MASK_IDX(si)]; -- cgit v1.2.3-59-g8ed1b From 275e928f19117d22f6d26dee94548baf4041b773 Mon Sep 17 00:00:00 2001 From: Amit Cohen Date: Wed, 29 May 2019 10:59:45 +0300 Subject: mlxsw: spectrum: Prevent force of 56G Force of 56G is not supported by hardware in Ethernet devices. This configuration fails with a bad parameter error from firmware. Add check of this case. Instead of trying to set 56G with autoneg off, return a meaningful error. Fixes: 56ade8fe3fe1 ("mlxsw: spectrum: Add initial support for Spectrum ASIC") Signed-off-by: Amit Cohen Acked-by: Jiri Pirko Signed-off-by: Ido Schimmel Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c index dbb425717f5e..dfe6b44baf63 100644 --- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c +++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c @@ -3128,6 +3128,10 @@ mlxsw_sp_port_set_link_ksettings(struct net_device *dev, ops->reg_ptys_eth_unpack(mlxsw_sp, ptys_pl, ð_proto_cap, NULL, NULL); autoneg = cmd->base.autoneg == AUTONEG_ENABLE; + if (!autoneg && cmd->base.speed == SPEED_56000) { + netdev_err(dev, "56G not supported with autoneg off\n"); + return -EINVAL; + } eth_proto_new = autoneg ? ops->to_ptys_advert_link(mlxsw_sp, cmd) : ops->to_ptys_speed(mlxsw_sp, cmd->base.speed); -- cgit v1.2.3-59-g8ed1b From 21808437214637952b61beaba6034d97880fbeb3 Mon Sep 17 00:00:00 2001 From: Antoine Tenart Date: Wed, 29 May 2019 15:59:48 +0200 Subject: net: mvpp2: fix bad MVPP2_TXQ_SCHED_TOKEN_CNTR_REG queue value MVPP2_TXQ_SCHED_TOKEN_CNTR_REG() expects the logical queue id but the current code is passing the global tx queue offset, so it ends up writing to unknown registers (between 0x8280 and 0x82fc, which seemed to be unused by the hardware). This fixes the issue by using the logical queue id instead. Fixes: 3f518509dedc ("ethernet: Add new driver for Marvell Armada 375 network unit") Signed-off-by: Antoine Tenart Signed-off-by: David S. Miller --- drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index d38952eb7aa9..7a67e23a2c2b 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -1455,7 +1455,7 @@ static inline void mvpp2_xlg_max_rx_size_set(struct mvpp2_port *port) /* Set defaults to the MVPP2 port */ static void mvpp2_defaults_set(struct mvpp2_port *port) { - int tx_port_num, val, queue, ptxq, lrxq; + int tx_port_num, val, queue, lrxq; if (port->priv->hw_version == MVPP21) { /* Update TX FIFO MIN Threshold */ @@ -1476,11 +1476,9 @@ static void mvpp2_defaults_set(struct mvpp2_port *port) mvpp2_write(port->priv, MVPP2_TXP_SCHED_FIXED_PRIO_REG, 0); /* Close bandwidth for all queues */ - for (queue = 0; queue < MVPP2_MAX_TXQ; queue++) { - ptxq = mvpp2_txq_phys(port->id, queue); + for (queue = 0; queue < MVPP2_MAX_TXQ; queue++) mvpp2_write(port->priv, - MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(ptxq), 0); - } + MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(queue), 0); /* Set refill period to 1 usec, refill tokens * and bucket size to maximum @@ -2336,7 +2334,7 @@ static void mvpp2_txq_deinit(struct mvpp2_port *port, txq->descs_dma = 0; /* Set minimum bandwidth for disabled TXQs */ - mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->id), 0); + mvpp2_write(port->priv, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->log_id), 0); /* Set Tx descriptors queue starting address and size */ thread = mvpp2_cpu_to_thread(port->priv, get_cpu()); -- cgit v1.2.3-59-g8ed1b