mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Merge branch 'net-bcmasp-collection-of-fixes'
Florian Fainelli says: ==================== net: bcmasp: Collection of fixes This patch series is a collection of bug fixes accumulated during a LLM coding session. Thanks to Justin for the internal review and helping with the last patch. ==================== Link: https://patch.msgid.link/20261013204439.3494046-1-florian.fainelli@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
38dda0ecd4
|
|
@ -511,6 +511,13 @@ static int bcmasp_netfilt_wr_to_hw(struct bcmasp_priv *priv,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool bcmasp_netfilt_is_companion(struct bcmasp_priv *priv, int i)
|
||||
{
|
||||
return i > 0 && (i % 2) &&
|
||||
priv->net_filters[i].wake_filter &&
|
||||
priv->net_filters[i - 1].wake_filter;
|
||||
}
|
||||
|
||||
void bcmasp_netfilt_suspend(struct bcmasp_intf *intf)
|
||||
{
|
||||
struct bcmasp_priv *priv = intf->parent;
|
||||
|
|
@ -524,9 +531,7 @@ void bcmasp_netfilt_suspend(struct bcmasp_intf *intf)
|
|||
priv->net_filters[i].port != intf->port)
|
||||
continue;
|
||||
|
||||
if (i > 0 && (i % 2) &&
|
||||
priv->net_filters[i].wake_filter &&
|
||||
priv->net_filters[i - 1].wake_filter)
|
||||
if (bcmasp_netfilt_is_companion(priv, i))
|
||||
continue;
|
||||
|
||||
ret = bcmasp_netfilt_wr_to_hw(priv, &priv->net_filters[i]);
|
||||
|
|
@ -556,9 +561,7 @@ int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
|
|||
priv->net_filters[i].port != intf->port)
|
||||
continue;
|
||||
|
||||
if (i > 0 && (i % 2) &&
|
||||
priv->net_filters[i].wake_filter &&
|
||||
priv->net_filters[i - 1].wake_filter)
|
||||
if (bcmasp_netfilt_is_companion(priv, i))
|
||||
continue;
|
||||
|
||||
if (j == *rule_cnt)
|
||||
|
|
@ -583,9 +586,7 @@ int bcmasp_netfilt_get_active(struct bcmasp_intf *intf)
|
|||
continue;
|
||||
|
||||
/* Skip over a wake filter pair */
|
||||
if (i > 0 && (i % 2) &&
|
||||
priv->net_filters[i].wake_filter &&
|
||||
priv->net_filters[i - 1].wake_filter)
|
||||
if (bcmasp_netfilt_is_companion(priv, i))
|
||||
continue;
|
||||
|
||||
cnt++;
|
||||
|
|
@ -607,6 +608,9 @@ bool bcmasp_netfilt_check_dup(struct bcmasp_intf *intf,
|
|||
priv->net_filters[i].port != intf->port)
|
||||
continue;
|
||||
|
||||
if (bcmasp_netfilt_is_companion(priv, i))
|
||||
continue;
|
||||
|
||||
cur = &priv->net_filters[i].fs;
|
||||
|
||||
if (cur->flow_type != fs->flow_type ||
|
||||
|
|
@ -659,7 +663,7 @@ bool bcmasp_netfilt_check_dup(struct bcmasp_intf *intf,
|
|||
}
|
||||
|
||||
/* If no network filter found, return open filter.
|
||||
* If no more open filters return NULL
|
||||
* If no more open filters return error.
|
||||
*/
|
||||
struct bcmasp_net_filter *bcmasp_netfilt_get_init(struct bcmasp_intf *intf,
|
||||
u32 loc, bool wake_filter,
|
||||
|
|
@ -669,45 +673,55 @@ struct bcmasp_net_filter *bcmasp_netfilt_get_init(struct bcmasp_intf *intf,
|
|||
struct bcmasp_priv *priv = intf->parent;
|
||||
int i, open_index = -1;
|
||||
|
||||
/* Check whether we exceed the filter table capacity */
|
||||
if (!init) {
|
||||
if (loc == RX_CLS_LOC_ANY || loc >= priv->num_net_filters)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
if (priv->net_filters[loc].claimed &&
|
||||
priv->net_filters[loc].port == intf->port &&
|
||||
!bcmasp_netfilt_is_companion(priv, loc))
|
||||
return &priv->net_filters[loc];
|
||||
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
if (loc != RX_CLS_LOC_ANY && loc >= priv->num_net_filters)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* If the filter location is busy (already claimed) and we are initializing
|
||||
* the filter (insertion), return a busy error code.
|
||||
*/
|
||||
if (loc != RX_CLS_LOC_ANY && init && priv->net_filters[loc].claimed)
|
||||
return ERR_PTR(-EBUSY);
|
||||
if (loc != RX_CLS_LOC_ANY) {
|
||||
if (priv->net_filters[loc].claimed)
|
||||
return ERR_PTR(-EBUSY);
|
||||
|
||||
/* We need two filters for wake-up, so we cannot use an odd filter */
|
||||
if (wake_filter && loc != RX_CLS_LOC_ANY && (loc % 2))
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* Initialize the loop index based on the desired location or from 0 */
|
||||
i = loc == RX_CLS_LOC_ANY ? 0 : loc;
|
||||
|
||||
for ( ; i < priv->num_net_filters; i++) {
|
||||
/* Found matching network filter */
|
||||
if (!init &&
|
||||
priv->net_filters[i].claimed &&
|
||||
priv->net_filters[i].hw_index == i &&
|
||||
priv->net_filters[i].port == intf->port)
|
||||
return &priv->net_filters[i];
|
||||
|
||||
/* If we don't need a new filter or new filter already found */
|
||||
if (!init || open_index >= 0)
|
||||
continue;
|
||||
|
||||
/* Wake filter conslidates two filters to cover more bytes
|
||||
* Wake filter is open if...
|
||||
* 1. It is an even filter
|
||||
* 2. The current and next filter is not claimed
|
||||
*/
|
||||
if (wake_filter && !(i % 2) && !priv->net_filters[i].claimed &&
|
||||
!priv->net_filters[i + 1].claimed)
|
||||
open_index = i;
|
||||
else if (!priv->net_filters[i].claimed)
|
||||
open_index = i;
|
||||
/* We need two filters for wake-up, so we cannot use an odd filter */
|
||||
if (wake_filter) {
|
||||
if ((loc % 2) || loc + 1 >= priv->num_net_filters)
|
||||
return ERR_PTR(-EINVAL);
|
||||
if (priv->net_filters[loc + 1].claimed)
|
||||
return ERR_PTR(-EBUSY);
|
||||
}
|
||||
open_index = loc;
|
||||
} else {
|
||||
for (i = 0; i < priv->num_net_filters; i++) {
|
||||
/* Wake filter consolidates two filters to cover more bytes.
|
||||
* Wake filter is open if:
|
||||
* 1. It is an even filter
|
||||
* 2. The current and next filter is not claimed
|
||||
*/
|
||||
if (wake_filter) {
|
||||
if (!(i % 2) && (i + 1 < priv->num_net_filters) &&
|
||||
!priv->net_filters[i].claimed &&
|
||||
!priv->net_filters[i + 1].claimed) {
|
||||
open_index = i;
|
||||
break;
|
||||
}
|
||||
} else if (!priv->net_filters[i].claimed) {
|
||||
open_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (open_index >= 0) {
|
||||
|
|
@ -716,16 +730,20 @@ struct bcmasp_net_filter *bcmasp_netfilt_get_init(struct bcmasp_intf *intf,
|
|||
nfilter->port = intf->port;
|
||||
nfilter->ch = intf->channel + priv->tx_chan_offset;
|
||||
nfilter->hw_index = open_index;
|
||||
|
||||
if (wake_filter) {
|
||||
/* Claim next filter */
|
||||
priv->net_filters[open_index + 1].claimed = true;
|
||||
priv->net_filters[open_index + 1].wake_filter = true;
|
||||
priv->net_filters[open_index + 1].hw_index = open_index + 1;
|
||||
priv->net_filters[open_index + 1].port = intf->port;
|
||||
priv->net_filters[open_index + 1].ch = intf->channel +
|
||||
priv->tx_chan_offset;
|
||||
nfilter->wake_filter = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (wake_filter && open_index >= 0) {
|
||||
/* Claim next filter */
|
||||
priv->net_filters[open_index + 1].claimed = true;
|
||||
priv->net_filters[open_index + 1].wake_filter = true;
|
||||
nfilter->wake_filter = true;
|
||||
}
|
||||
|
||||
return nfilter ? nfilter : ERR_PTR(-EINVAL);
|
||||
return nfilter ? nfilter : ERR_PTR(-ENOSPC);
|
||||
}
|
||||
|
||||
void bcmasp_netfilt_release(struct bcmasp_intf *intf,
|
||||
|
|
@ -733,7 +751,8 @@ void bcmasp_netfilt_release(struct bcmasp_intf *intf,
|
|||
{
|
||||
struct bcmasp_priv *priv = intf->parent;
|
||||
|
||||
if (nfilt->wake_filter) {
|
||||
if (nfilt->wake_filter && !(nfilt->hw_index % 2) &&
|
||||
nfilt->hw_index + 1 < priv->num_net_filters) {
|
||||
memset(&priv->net_filters[nfilt->hw_index + 1], 0,
|
||||
sizeof(struct bcmasp_net_filter));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -250,10 +250,6 @@ struct bcmasp_intf_stats64 {
|
|||
};
|
||||
|
||||
struct bcmasp_mib_counters {
|
||||
u32 edpkt_ts;
|
||||
u32 edpkt_rx_pkt_cnt;
|
||||
u32 edpkt_hdr_ext_cnt;
|
||||
u32 edpkt_hdr_out_cnt;
|
||||
u32 umac_frm_cnt;
|
||||
u32 fb_frm_cnt;
|
||||
u32 fb_rx_fifo_depth;
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ static struct sk_buff *bcmasp_csum_offload(struct net_device *dev,
|
|||
static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
{
|
||||
struct bcmasp_intf *intf = netdev_priv(dev);
|
||||
unsigned int total_bytes, size;
|
||||
unsigned int total_bytes, size, min_size;
|
||||
int spb_index, nr_frags, i, j;
|
||||
struct bcmasp_tx_cb *txcb;
|
||||
dma_addr_t mapping, valid;
|
||||
|
|
@ -262,16 +262,21 @@ static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
if (!skb)
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
min_size = ETH_ZLEN + ETH_FCS_LEN;
|
||||
if (csum_hw)
|
||||
min_size += sizeof(struct bcmasp_pkt_offload);
|
||||
|
||||
if (skb->len < min_size) {
|
||||
if (skb_put_padto(skb, min_size))
|
||||
return NETDEV_TX_OK;
|
||||
nr_frags = skb_shinfo(skb)->nr_frags;
|
||||
}
|
||||
|
||||
spb_index = intf->tx_spb_index;
|
||||
valid = intf->tx_spb_dma_valid;
|
||||
for (i = 0; i <= nr_frags; i++) {
|
||||
if (!i) {
|
||||
size = skb_headlen(skb);
|
||||
if (!nr_frags && size < (ETH_ZLEN + ETH_FCS_LEN)) {
|
||||
if (skb_put_padto(skb, ETH_ZLEN + ETH_FCS_LEN))
|
||||
return NETDEV_TX_OK;
|
||||
size = skb->len;
|
||||
}
|
||||
mapping = dma_map_single(kdev, skb->data, size,
|
||||
DMA_TO_DEVICE);
|
||||
} else {
|
||||
|
|
@ -285,6 +290,11 @@ static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
intf->mib.tx_dma_failed++;
|
||||
spb_index = intf->tx_spb_index;
|
||||
for (j = 0; j < i; j++) {
|
||||
txcb = &intf->tx_cbs[spb_index];
|
||||
dma_unmap_single(kdev,
|
||||
dma_unmap_addr(txcb, dma_addr),
|
||||
dma_unmap_len(txcb, dma_len),
|
||||
DMA_TO_DEVICE);
|
||||
bcmasp_clean_txcb(intf, spb_index);
|
||||
spb_index = incr_ring(spb_index,
|
||||
DESC_RING_COUNT);
|
||||
|
|
@ -518,6 +528,12 @@ static int bcmasp_rx_poll(struct napi_struct *napi, int budget)
|
|||
DMA_FROM_DEVICE);
|
||||
|
||||
len = desc->size;
|
||||
if (unlikely(len < 2 + ETH_HLEN + (intf->crc_fwd ? ETH_FCS_LEN : 0))) {
|
||||
u64_stats_update_begin(&stats->syncp);
|
||||
u64_stats_inc(&stats->rx_dropped);
|
||||
u64_stats_update_end(&stats->syncp);
|
||||
goto next;
|
||||
}
|
||||
|
||||
/* Allocate a page pool page as the SKB data area so the
|
||||
* kernel can recycle it efficiently after the packet is
|
||||
|
|
@ -1287,7 +1303,7 @@ struct bcmasp_intf *bcmasp_interface_create(struct bcmasp_priv *priv,
|
|||
ndev_dn->name);
|
||||
goto err_free_netdev;
|
||||
}
|
||||
intf->phy_dn = ndev_dn;
|
||||
intf->phy_dn = of_node_get(ndev_dn);
|
||||
}
|
||||
|
||||
/* Map resource */
|
||||
|
|
@ -1327,6 +1343,7 @@ struct bcmasp_intf *bcmasp_interface_create(struct bcmasp_priv *priv,
|
|||
err_deregister_fixed_link:
|
||||
if (of_phy_is_fixed_link(ndev_dn))
|
||||
of_phy_deregister_fixed_link(ndev_dn);
|
||||
of_node_put(intf->phy_dn);
|
||||
err_free_netdev:
|
||||
free_netdev(ndev);
|
||||
err:
|
||||
|
|
@ -1339,6 +1356,7 @@ void bcmasp_interface_destroy(struct bcmasp_intf *intf)
|
|||
unregister_netdev(intf->ndev);
|
||||
if (of_phy_is_fixed_link(intf->ndev_dn))
|
||||
of_phy_deregister_fixed_link(intf->ndev_dn);
|
||||
of_node_put(intf->phy_dn);
|
||||
free_netdev(intf->ndev);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user