diff options
Diffstat (limited to 'drivers')
43 files changed, 569 insertions, 414 deletions
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); } } } +} 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); 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); 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: diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index 350e385528fd..941b0beb87ef 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; @@ -298,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), @@ -389,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); } } 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..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); @@ -713,38 +712,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; } } } diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 8314c00d7537..f758b2e0591f 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; } @@ -6377,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; @@ -7616,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); @@ -8530,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) && @@ -10434,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. */ @@ -10722,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); diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index eca36dd6b751..be438d82f939 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -20,6 +20,7 @@ #include <linux/interrupt.h> #include <linux/rhashtable.h> +#include <linux/crash_dump.h> #include <net/devlink.h> #include <net/dst_metadata.h> #include <net/xdp.h> @@ -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) \ @@ -1790,7 +1792,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) { 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); 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; } 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) | 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 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); 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); 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, 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 <linux/net_tstamp.h> +#include <linux/nospec.h> #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; 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); 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); 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++; 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()); 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) && 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) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c b/drivers/net/ethernet/mellanox/mlx5/core/fs_core.c index d7ca7e82a832..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; @@ -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) @@ -2474,11 +2476,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 +2489,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 +2505,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) { @@ -2637,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; } @@ -2664,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; } 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); 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); 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)]; 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; 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) 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); } 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; } 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; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 2a1052704885..65e57b9f6887 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); } /** @@ -4379,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_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; } 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 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); diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index fd35131a0c39..c71c7d0f53f0 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c @@ -26,10 +26,18 @@ /* 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 #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) @@ -247,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) @@ -277,6 +283,33 @@ 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; + + /* 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 */ if (phy_interrupt_is_valid(phydev)) { val = phy_read(phydev, DP83867_CFG3); @@ -307,7 +340,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[] = { 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; 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); |