Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Merge in late fixes to prepare for the 6.10 net-next PR.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2024-05-14 10:52:25 -07:00
commit 654de42f3f
36 changed files with 438 additions and 298 deletions

View File

@ -449,7 +449,7 @@ static int dpll_pin_prop_dup(const struct dpll_pin_properties *src,
sizeof(*src->freq_supported); sizeof(*src->freq_supported);
dst->freq_supported = kmemdup(src->freq_supported, dst->freq_supported = kmemdup(src->freq_supported,
freq_size, GFP_KERNEL); freq_size, GFP_KERNEL);
if (!src->freq_supported) if (!dst->freq_supported)
return -ENOMEM; return -ENOMEM;
} }
if (src->board_label) { if (src->board_label) {

View File

@ -1107,10 +1107,13 @@ static void gmac_tx_irq_enable(struct net_device *netdev,
{ {
struct gemini_ethernet_port *port = netdev_priv(netdev); struct gemini_ethernet_port *port = netdev_priv(netdev);
struct gemini_ethernet *geth = port->geth; struct gemini_ethernet *geth = port->geth;
unsigned long flags;
u32 val, mask; u32 val, mask;
netdev_dbg(netdev, "%s device %d\n", __func__, netdev->dev_id); netdev_dbg(netdev, "%s device %d\n", __func__, netdev->dev_id);
spin_lock_irqsave(&geth->irq_lock, flags);
mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq); mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq);
if (en) if (en)
@ -1119,6 +1122,8 @@ static void gmac_tx_irq_enable(struct net_device *netdev,
val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG);
val = en ? val | mask : val & ~mask; val = en ? val | mask : val & ~mask;
writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG);
spin_unlock_irqrestore(&geth->irq_lock, flags);
} }
static void gmac_tx_irq(struct net_device *netdev, unsigned int txq_num) static void gmac_tx_irq(struct net_device *netdev, unsigned int txq_num)
@ -1415,15 +1420,19 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
union gmac_rxdesc_3 word3; union gmac_rxdesc_3 word3;
struct page *page = NULL; struct page *page = NULL;
unsigned int page_offs; unsigned int page_offs;
unsigned long flags;
unsigned short r, w; unsigned short r, w;
union dma_rwptr rw; union dma_rwptr rw;
dma_addr_t mapping; dma_addr_t mapping;
int frag_nr = 0; int frag_nr = 0;
spin_lock_irqsave(&geth->irq_lock, flags);
rw.bits32 = readl(ptr_reg); rw.bits32 = readl(ptr_reg);
/* Reset interrupt as all packages until here are taken into account */ /* Reset interrupt as all packages until here are taken into account */
writel(DEFAULT_Q0_INT_BIT << netdev->dev_id, writel(DEFAULT_Q0_INT_BIT << netdev->dev_id,
geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); geth->base + GLOBAL_INTERRUPT_STATUS_1_REG);
spin_unlock_irqrestore(&geth->irq_lock, flags);
r = rw.bits.rptr; r = rw.bits.rptr;
w = rw.bits.wptr; w = rw.bits.wptr;
@ -1726,10 +1735,9 @@ static irqreturn_t gmac_irq(int irq, void *data)
gmac_update_hw_stats(netdev); gmac_update_hw_stats(netdev);
if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) { if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) {
spin_lock(&geth->irq_lock);
writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8), writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8),
geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); geth->base + GLOBAL_INTERRUPT_STATUS_4_REG);
spin_lock(&geth->irq_lock);
u64_stats_update_begin(&port->ir_stats_syncp); u64_stats_update_begin(&port->ir_stats_syncp);
++port->stats.rx_fifo_errors; ++port->stats.rx_fifo_errors;
u64_stats_update_end(&port->ir_stats_syncp); u64_stats_update_end(&port->ir_stats_syncp);

View File

@ -3674,29 +3674,6 @@ fec_set_mac_address(struct net_device *ndev, void *p)
return 0; return 0;
} }
#ifdef CONFIG_NET_POLL_CONTROLLER
/**
* fec_poll_controller - FEC Poll controller function
* @dev: The FEC network adapter
*
* Polled functionality used by netconsole and others in non interrupt mode
*
*/
static void fec_poll_controller(struct net_device *dev)
{
int i;
struct fec_enet_private *fep = netdev_priv(dev);
for (i = 0; i < FEC_IRQ_NUM; i++) {
if (fep->irq[i] > 0) {
disable_irq(fep->irq[i]);
fec_enet_interrupt(fep->irq[i], dev);
enable_irq(fep->irq[i]);
}
}
}
#endif
static inline void fec_enet_set_netdev_features(struct net_device *netdev, static inline void fec_enet_set_netdev_features(struct net_device *netdev,
netdev_features_t features) netdev_features_t features)
{ {
@ -4003,9 +3980,6 @@ static const struct net_device_ops fec_netdev_ops = {
.ndo_tx_timeout = fec_timeout, .ndo_tx_timeout = fec_timeout,
.ndo_set_mac_address = fec_set_mac_address, .ndo_set_mac_address = fec_set_mac_address,
.ndo_eth_ioctl = phy_do_ioctl_running, .ndo_eth_ioctl = phy_do_ioctl_running,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = fec_poll_controller,
#endif
.ndo_set_features = fec_set_features, .ndo_set_features = fec_set_features,
.ndo_bpf = fec_enet_bpf, .ndo_bpf = fec_enet_bpf,
.ndo_xdp_xmit = fec_enet_xdp_xmit, .ndo_xdp_xmit = fec_enet_xdp_xmit,

View File

@ -1434,13 +1434,13 @@ ice_dwnld_sign_and_cfg_segs(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,
goto exit; goto exit;
} }
count = le32_to_cpu(seg->signed_buf_count);
state = ice_download_pkg_sig_seg(hw, seg);
if (state || !count)
goto exit;
conf_idx = le32_to_cpu(seg->signed_seg_idx); conf_idx = le32_to_cpu(seg->signed_seg_idx);
start = le32_to_cpu(seg->signed_buf_start); start = le32_to_cpu(seg->signed_buf_start);
count = le32_to_cpu(seg->signed_buf_count);
state = ice_download_pkg_sig_seg(hw, seg);
if (state)
goto exit;
state = ice_download_pkg_config_seg(hw, pkg_hdr, conf_idx, start, state = ice_download_pkg_config_seg(hw, pkg_hdr, conf_idx, start,
count); count);

View File

@ -110,16 +110,16 @@ static const struct mtk_reg_map mt7986_reg_map = {
.tx_irq_mask = 0x461c, .tx_irq_mask = 0x461c,
.tx_irq_status = 0x4618, .tx_irq_status = 0x4618,
.pdma = { .pdma = {
.rx_ptr = 0x6100, .rx_ptr = 0x4100,
.rx_cnt_cfg = 0x6104, .rx_cnt_cfg = 0x4104,
.pcrx_ptr = 0x6108, .pcrx_ptr = 0x4108,
.glo_cfg = 0x6204, .glo_cfg = 0x4204,
.rst_idx = 0x6208, .rst_idx = 0x4208,
.delay_irq = 0x620c, .delay_irq = 0x420c,
.irq_status = 0x6220, .irq_status = 0x4220,
.irq_mask = 0x6228, .irq_mask = 0x4228,
.adma_rx_dbg0 = 0x6238, .adma_rx_dbg0 = 0x4238,
.int_grp = 0x6250, .int_grp = 0x4250,
}, },
.qdma = { .qdma = {
.qtx_cfg = 0x4400, .qtx_cfg = 0x4400,
@ -1107,7 +1107,7 @@ static bool mtk_rx_get_desc(struct mtk_eth *eth, struct mtk_rx_dma_v2 *rxd,
rxd->rxd1 = READ_ONCE(dma_rxd->rxd1); rxd->rxd1 = READ_ONCE(dma_rxd->rxd1);
rxd->rxd3 = READ_ONCE(dma_rxd->rxd3); rxd->rxd3 = READ_ONCE(dma_rxd->rxd3);
rxd->rxd4 = READ_ONCE(dma_rxd->rxd4); rxd->rxd4 = READ_ONCE(dma_rxd->rxd4);
if (mtk_is_netsys_v2_or_greater(eth)) { if (mtk_is_netsys_v3_or_greater(eth)) {
rxd->rxd5 = READ_ONCE(dma_rxd->rxd5); rxd->rxd5 = READ_ONCE(dma_rxd->rxd5);
rxd->rxd6 = READ_ONCE(dma_rxd->rxd6); rxd->rxd6 = READ_ONCE(dma_rxd->rxd6);
} }
@ -1139,7 +1139,7 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
eth->scratch_ring = eth->sram_base; eth->scratch_ring = eth->sram_base;
else else
eth->scratch_ring = dma_alloc_coherent(eth->dma_dev, eth->scratch_ring = dma_alloc_coherent(eth->dma_dev,
cnt * soc->txrx.txd_size, cnt * soc->tx.desc_size,
&eth->phy_scratch_ring, &eth->phy_scratch_ring,
GFP_KERNEL); GFP_KERNEL);
if (unlikely(!eth->scratch_ring)) if (unlikely(!eth->scratch_ring))
@ -1155,17 +1155,17 @@ static int mtk_init_fq_dma(struct mtk_eth *eth)
if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr)))
return -ENOMEM; return -ENOMEM;
phy_ring_tail = eth->phy_scratch_ring + soc->txrx.txd_size * (cnt - 1); phy_ring_tail = eth->phy_scratch_ring + soc->tx.desc_size * (cnt - 1);
for (i = 0; i < cnt; i++) { for (i = 0; i < cnt; i++) {
dma_addr_t addr = dma_addr + i * MTK_QDMA_PAGE_SIZE; dma_addr_t addr = dma_addr + i * MTK_QDMA_PAGE_SIZE;
struct mtk_tx_dma_v2 *txd; struct mtk_tx_dma_v2 *txd;
txd = eth->scratch_ring + i * soc->txrx.txd_size; txd = eth->scratch_ring + i * soc->tx.desc_size;
txd->txd1 = addr; txd->txd1 = addr;
if (i < cnt - 1) if (i < cnt - 1)
txd->txd2 = eth->phy_scratch_ring + txd->txd2 = eth->phy_scratch_ring +
(i + 1) * soc->txrx.txd_size; (i + 1) * soc->tx.desc_size;
txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE); txd->txd3 = TX_DMA_PLEN0(MTK_QDMA_PAGE_SIZE);
if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA)) if (MTK_HAS_CAPS(soc->caps, MTK_36BIT_DMA))
@ -1416,7 +1416,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
if (itxd == ring->last_free) if (itxd == ring->last_free)
return -ENOMEM; return -ENOMEM;
itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size); itx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
memset(itx_buf, 0, sizeof(*itx_buf)); memset(itx_buf, 0, sizeof(*itx_buf));
txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size, txd_info.addr = dma_map_single(eth->dma_dev, skb->data, txd_info.size,
@ -1457,7 +1457,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info)); memset(&txd_info, 0, sizeof(struct mtk_tx_dma_desc_info));
txd_info.size = min_t(unsigned int, frag_size, txd_info.size = min_t(unsigned int, frag_size,
soc->txrx.dma_max_len); soc->tx.dma_max_len);
txd_info.qid = queue; txd_info.qid = queue;
txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 && txd_info.last = i == skb_shinfo(skb)->nr_frags - 1 &&
!(frag_size - txd_info.size); !(frag_size - txd_info.size);
@ -1470,7 +1470,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
mtk_tx_set_dma_desc(dev, txd, &txd_info); mtk_tx_set_dma_desc(dev, txd, &txd_info);
tx_buf = mtk_desc_to_tx_buf(ring, txd, tx_buf = mtk_desc_to_tx_buf(ring, txd,
soc->txrx.txd_size); soc->tx.desc_size);
if (new_desc) if (new_desc)
memset(tx_buf, 0, sizeof(*tx_buf)); memset(tx_buf, 0, sizeof(*tx_buf));
tx_buf->data = (void *)MTK_DMA_DUMMY_DESC; tx_buf->data = (void *)MTK_DMA_DUMMY_DESC;
@ -1513,7 +1513,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
} else { } else {
int next_idx; int next_idx;
next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->txrx.txd_size), next_idx = NEXT_DESP_IDX(txd_to_idx(ring, txd, soc->tx.desc_size),
ring->dma_size); ring->dma_size);
mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0); mtk_w32(eth, next_idx, MT7628_TX_CTX_IDX0);
} }
@ -1522,7 +1522,7 @@ static int mtk_tx_map(struct sk_buff *skb, struct net_device *dev,
err_dma: err_dma:
do { do {
tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->txrx.txd_size); tx_buf = mtk_desc_to_tx_buf(ring, itxd, soc->tx.desc_size);
/* unmap dma */ /* unmap dma */
mtk_tx_unmap(eth, tx_buf, NULL, false); mtk_tx_unmap(eth, tx_buf, NULL, false);
@ -1547,7 +1547,7 @@ static int mtk_cal_txd_req(struct mtk_eth *eth, struct sk_buff *skb)
for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
frag = &skb_shinfo(skb)->frags[i]; frag = &skb_shinfo(skb)->frags[i];
nfrags += DIV_ROUND_UP(skb_frag_size(frag), nfrags += DIV_ROUND_UP(skb_frag_size(frag),
eth->soc->txrx.dma_max_len); eth->soc->tx.dma_max_len);
} }
} else { } else {
nfrags += skb_shinfo(skb)->nr_frags; nfrags += skb_shinfo(skb)->nr_frags;
@ -1654,7 +1654,7 @@ static struct mtk_rx_ring *mtk_get_rx_ring(struct mtk_eth *eth)
ring = &eth->rx_ring[i]; ring = &eth->rx_ring[i];
idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
rxd = ring->dma + idx * eth->soc->txrx.rxd_size; rxd = ring->dma + idx * eth->soc->rx.desc_size;
if (rxd->rxd2 & RX_DMA_DONE) { if (rxd->rxd2 & RX_DMA_DONE) {
ring->calc_idx_update = true; ring->calc_idx_update = true;
return ring; return ring;
@ -1822,7 +1822,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf,
} }
htxd = txd; htxd = txd;
tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->txrx.txd_size); tx_buf = mtk_desc_to_tx_buf(ring, txd, soc->tx.desc_size);
memset(tx_buf, 0, sizeof(*tx_buf)); memset(tx_buf, 0, sizeof(*tx_buf));
htx_buf = tx_buf; htx_buf = tx_buf;
@ -1841,7 +1841,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf,
goto unmap; goto unmap;
tx_buf = mtk_desc_to_tx_buf(ring, txd, tx_buf = mtk_desc_to_tx_buf(ring, txd,
soc->txrx.txd_size); soc->tx.desc_size);
memset(tx_buf, 0, sizeof(*tx_buf)); memset(tx_buf, 0, sizeof(*tx_buf));
n_desc++; n_desc++;
} }
@ -1879,7 +1879,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf,
} else { } else {
int idx; int idx;
idx = txd_to_idx(ring, txd, soc->txrx.txd_size); idx = txd_to_idx(ring, txd, soc->tx.desc_size);
mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size), mtk_w32(eth, NEXT_DESP_IDX(idx, ring->dma_size),
MT7628_TX_CTX_IDX0); MT7628_TX_CTX_IDX0);
} }
@ -1890,7 +1890,7 @@ static int mtk_xdp_submit_frame(struct mtk_eth *eth, struct xdp_frame *xdpf,
unmap: unmap:
while (htxd != txd) { while (htxd != txd) {
tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->txrx.txd_size); tx_buf = mtk_desc_to_tx_buf(ring, htxd, soc->tx.desc_size);
mtk_tx_unmap(eth, tx_buf, NULL, false); mtk_tx_unmap(eth, tx_buf, NULL, false);
htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU; htxd->txd3 = TX_DMA_LS0 | TX_DMA_OWNER_CPU;
@ -2021,14 +2021,14 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
goto rx_done; goto rx_done;
idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size); idx = NEXT_DESP_IDX(ring->calc_idx, ring->dma_size);
rxd = ring->dma + idx * eth->soc->txrx.rxd_size; rxd = ring->dma + idx * eth->soc->rx.desc_size;
data = ring->data[idx]; data = ring->data[idx];
if (!mtk_rx_get_desc(eth, &trxd, rxd)) if (!mtk_rx_get_desc(eth, &trxd, rxd))
break; break;
/* find out which mac the packet come from. values start at 1 */ /* find out which mac the packet come from. values start at 1 */
if (mtk_is_netsys_v2_or_greater(eth)) { if (mtk_is_netsys_v3_or_greater(eth)) {
u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5); u32 val = RX_DMA_GET_SPORT_V2(trxd.rxd5);
switch (val) { switch (val) {
@ -2140,7 +2140,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
skb->dev = netdev; skb->dev = netdev;
bytes += skb->len; bytes += skb->len;
if (mtk_is_netsys_v2_or_greater(eth)) { if (mtk_is_netsys_v3_or_greater(eth)) {
reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5); reason = FIELD_GET(MTK_RXD5_PPE_CPU_REASON, trxd.rxd5);
hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY; hash = trxd.rxd5 & MTK_RXD5_FOE_ENTRY;
if (hash != MTK_RXD5_FOE_ENTRY) if (hash != MTK_RXD5_FOE_ENTRY)
@ -2156,7 +2156,7 @@ static int mtk_poll_rx(struct napi_struct *napi, int budget,
rxdcsum = &trxd.rxd4; rxdcsum = &trxd.rxd4;
} }
if (*rxdcsum & eth->soc->txrx.rx_dma_l4_valid) if (*rxdcsum & eth->soc->rx.dma_l4_valid)
skb->ip_summed = CHECKSUM_UNNECESSARY; skb->ip_summed = CHECKSUM_UNNECESSARY;
else else
skb_checksum_none_assert(skb); skb_checksum_none_assert(skb);
@ -2280,7 +2280,7 @@ static int mtk_poll_tx_qdma(struct mtk_eth *eth, int budget,
break; break;
tx_buf = mtk_desc_to_tx_buf(ring, desc, tx_buf = mtk_desc_to_tx_buf(ring, desc,
eth->soc->txrx.txd_size); eth->soc->tx.desc_size);
if (!tx_buf->data) if (!tx_buf->data)
break; break;
@ -2331,7 +2331,7 @@ static int mtk_poll_tx_pdma(struct mtk_eth *eth, int budget,
} }
mtk_tx_unmap(eth, tx_buf, &bq, true); mtk_tx_unmap(eth, tx_buf, &bq, true);
desc = ring->dma + cpu * eth->soc->txrx.txd_size; desc = ring->dma + cpu * eth->soc->tx.desc_size;
ring->last_free = desc; ring->last_free = desc;
atomic_inc(&ring->free_count); atomic_inc(&ring->free_count);
@ -2421,7 +2421,7 @@ static int mtk_napi_rx(struct napi_struct *napi, int budget)
do { do {
int rx_done; int rx_done;
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, mtk_w32(eth, eth->soc->rx.irq_done_mask,
reg_map->pdma.irq_status); reg_map->pdma.irq_status);
rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth); rx_done = mtk_poll_rx(napi, budget - rx_done_total, eth);
rx_done_total += rx_done; rx_done_total += rx_done;
@ -2437,10 +2437,10 @@ static int mtk_napi_rx(struct napi_struct *napi, int budget)
return budget; return budget;
} while (mtk_r32(eth, reg_map->pdma.irq_status) & } while (mtk_r32(eth, reg_map->pdma.irq_status) &
eth->soc->txrx.rx_irq_done_mask); eth->soc->rx.irq_done_mask);
if (napi_complete_done(napi, rx_done_total)) if (napi_complete_done(napi, rx_done_total))
mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask); mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
return rx_done_total; return rx_done_total;
} }
@ -2449,7 +2449,7 @@ static int mtk_tx_alloc(struct mtk_eth *eth)
{ {
const struct mtk_soc_data *soc = eth->soc; const struct mtk_soc_data *soc = eth->soc;
struct mtk_tx_ring *ring = &eth->tx_ring; struct mtk_tx_ring *ring = &eth->tx_ring;
int i, sz = soc->txrx.txd_size; int i, sz = soc->tx.desc_size;
struct mtk_tx_dma_v2 *txd; struct mtk_tx_dma_v2 *txd;
int ring_size; int ring_size;
u32 ofs, val; u32 ofs, val;
@ -2572,14 +2572,14 @@ static void mtk_tx_clean(struct mtk_eth *eth)
} }
if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) { if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && ring->dma) {
dma_free_coherent(eth->dma_dev, dma_free_coherent(eth->dma_dev,
ring->dma_size * soc->txrx.txd_size, ring->dma_size * soc->tx.desc_size,
ring->dma, ring->phys); ring->dma, ring->phys);
ring->dma = NULL; ring->dma = NULL;
} }
if (ring->dma_pdma) { if (ring->dma_pdma) {
dma_free_coherent(eth->dma_dev, dma_free_coherent(eth->dma_dev,
ring->dma_size * soc->txrx.txd_size, ring->dma_size * soc->tx.desc_size,
ring->dma_pdma, ring->phys_pdma); ring->dma_pdma, ring->phys_pdma);
ring->dma_pdma = NULL; ring->dma_pdma = NULL;
} }
@ -2634,15 +2634,15 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) || if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SRAM) ||
rx_flag != MTK_RX_FLAGS_NORMAL) { rx_flag != MTK_RX_FLAGS_NORMAL) {
ring->dma = dma_alloc_coherent(eth->dma_dev, ring->dma = dma_alloc_coherent(eth->dma_dev,
rx_dma_size * eth->soc->txrx.rxd_size, rx_dma_size * eth->soc->rx.desc_size,
&ring->phys, GFP_KERNEL); &ring->phys, GFP_KERNEL);
} else { } else {
struct mtk_tx_ring *tx_ring = &eth->tx_ring; struct mtk_tx_ring *tx_ring = &eth->tx_ring;
ring->dma = tx_ring->dma + tx_ring_size * ring->dma = tx_ring->dma + tx_ring_size *
eth->soc->txrx.txd_size * (ring_no + 1); eth->soc->tx.desc_size * (ring_no + 1);
ring->phys = tx_ring->phys + tx_ring_size * ring->phys = tx_ring->phys + tx_ring_size *
eth->soc->txrx.txd_size * (ring_no + 1); eth->soc->tx.desc_size * (ring_no + 1);
} }
if (!ring->dma) if (!ring->dma)
@ -2653,7 +2653,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
dma_addr_t dma_addr; dma_addr_t dma_addr;
void *data; void *data;
rxd = ring->dma + i * eth->soc->txrx.rxd_size; rxd = ring->dma + i * eth->soc->rx.desc_size;
if (ring->page_pool) { if (ring->page_pool) {
data = mtk_page_pool_get_buff(ring->page_pool, data = mtk_page_pool_get_buff(ring->page_pool,
&dma_addr, GFP_KERNEL); &dma_addr, GFP_KERNEL);
@ -2690,7 +2690,7 @@ static int mtk_rx_alloc(struct mtk_eth *eth, int ring_no, int rx_flag)
rxd->rxd3 = 0; rxd->rxd3 = 0;
rxd->rxd4 = 0; rxd->rxd4 = 0;
if (mtk_is_netsys_v2_or_greater(eth)) { if (mtk_is_netsys_v3_or_greater(eth)) {
rxd->rxd5 = 0; rxd->rxd5 = 0;
rxd->rxd6 = 0; rxd->rxd6 = 0;
rxd->rxd7 = 0; rxd->rxd7 = 0;
@ -2744,7 +2744,7 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_
if (!ring->data[i]) if (!ring->data[i])
continue; continue;
rxd = ring->dma + i * eth->soc->txrx.rxd_size; rxd = ring->dma + i * eth->soc->rx.desc_size;
if (!rxd->rxd1) if (!rxd->rxd1)
continue; continue;
@ -2761,7 +2761,7 @@ static void mtk_rx_clean(struct mtk_eth *eth, struct mtk_rx_ring *ring, bool in_
if (!in_sram && ring->dma) { if (!in_sram && ring->dma) {
dma_free_coherent(eth->dma_dev, dma_free_coherent(eth->dma_dev,
ring->dma_size * eth->soc->txrx.rxd_size, ring->dma_size * eth->soc->rx.desc_size,
ring->dma, ring->phys); ring->dma, ring->phys);
ring->dma = NULL; ring->dma = NULL;
} }
@ -3124,7 +3124,7 @@ static void mtk_dma_free(struct mtk_eth *eth)
netdev_reset_queue(eth->netdev[i]); netdev_reset_queue(eth->netdev[i]);
if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) { if (!MTK_HAS_CAPS(soc->caps, MTK_SRAM) && eth->scratch_ring) {
dma_free_coherent(eth->dma_dev, dma_free_coherent(eth->dma_dev,
MTK_QDMA_RING_SIZE * soc->txrx.txd_size, MTK_QDMA_RING_SIZE * soc->tx.desc_size,
eth->scratch_ring, eth->phy_scratch_ring); eth->scratch_ring, eth->phy_scratch_ring);
eth->scratch_ring = NULL; eth->scratch_ring = NULL;
eth->phy_scratch_ring = 0; eth->phy_scratch_ring = 0;
@ -3174,7 +3174,7 @@ static irqreturn_t mtk_handle_irq_rx(int irq, void *_eth)
eth->rx_events++; eth->rx_events++;
if (likely(napi_schedule_prep(&eth->rx_napi))) { if (likely(napi_schedule_prep(&eth->rx_napi))) {
mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
__napi_schedule(&eth->rx_napi); __napi_schedule(&eth->rx_napi);
} }
@ -3200,9 +3200,9 @@ static irqreturn_t mtk_handle_irq(int irq, void *_eth)
const struct mtk_reg_map *reg_map = eth->soc->reg_map; const struct mtk_reg_map *reg_map = eth->soc->reg_map;
if (mtk_r32(eth, reg_map->pdma.irq_mask) & if (mtk_r32(eth, reg_map->pdma.irq_mask) &
eth->soc->txrx.rx_irq_done_mask) { eth->soc->rx.irq_done_mask) {
if (mtk_r32(eth, reg_map->pdma.irq_status) & if (mtk_r32(eth, reg_map->pdma.irq_status) &
eth->soc->txrx.rx_irq_done_mask) eth->soc->rx.irq_done_mask)
mtk_handle_irq_rx(irq, _eth); mtk_handle_irq_rx(irq, _eth);
} }
if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) { if (mtk_r32(eth, reg_map->tx_irq_mask) & MTK_TX_DONE_INT) {
@ -3220,10 +3220,10 @@ static void mtk_poll_controller(struct net_device *dev)
struct mtk_eth *eth = mac->hw; struct mtk_eth *eth = mac->hw;
mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
mtk_handle_irq_rx(eth->irq[2], dev); mtk_handle_irq_rx(eth->irq[2], dev);
mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_enable(eth, eth->soc->txrx.rx_irq_done_mask); mtk_rx_irq_enable(eth, eth->soc->rx.irq_done_mask);
} }
#endif #endif
@ -3387,7 +3387,7 @@ static int mtk_open(struct net_device *dev)
napi_enable(&eth->tx_napi); napi_enable(&eth->tx_napi);
napi_enable(&eth->rx_napi); napi_enable(&eth->rx_napi);
mtk_tx_irq_enable(eth, MTK_TX_DONE_INT); mtk_tx_irq_enable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_enable(eth, soc->txrx.rx_irq_done_mask); mtk_rx_irq_enable(eth, soc->rx.irq_done_mask);
refcount_set(&eth->dma_refcnt, 1); refcount_set(&eth->dma_refcnt, 1);
} }
else else
@ -3471,7 +3471,7 @@ static int mtk_stop(struct net_device *dev)
mtk_gdm_config(eth, MTK_GDMA_DROP_ALL); mtk_gdm_config(eth, MTK_GDMA_DROP_ALL);
mtk_tx_irq_disable(eth, MTK_TX_DONE_INT); mtk_tx_irq_disable(eth, MTK_TX_DONE_INT);
mtk_rx_irq_disable(eth, eth->soc->txrx.rx_irq_done_mask); mtk_rx_irq_disable(eth, eth->soc->rx.irq_done_mask);
napi_disable(&eth->tx_napi); napi_disable(&eth->tx_napi);
napi_disable(&eth->rx_napi); napi_disable(&eth->rx_napi);
@ -3893,7 +3893,7 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
else else
mtk_hw_reset(eth); mtk_hw_reset(eth);
if (mtk_is_netsys_v2_or_greater(eth)) { if (mtk_is_netsys_v3_or_greater(eth)) {
/* Set FE to PDMAv2 if necessary */ /* Set FE to PDMAv2 if necessary */
val = mtk_r32(eth, MTK_FE_GLO_MISC); val = mtk_r32(eth, MTK_FE_GLO_MISC);
mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC); mtk_w32(eth, val | BIT(4), MTK_FE_GLO_MISC);
@ -3947,9 +3947,9 @@ static int mtk_hw_init(struct mtk_eth *eth, bool reset)
/* FE int grouping */ /* FE int grouping */
mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp); mtk_w32(eth, MTK_TX_DONE_INT, reg_map->pdma.int_grp);
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->pdma.int_grp + 4); mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->pdma.int_grp + 4);
mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp); mtk_w32(eth, MTK_TX_DONE_INT, reg_map->qdma.int_grp);
mtk_w32(eth, eth->soc->txrx.rx_irq_done_mask, reg_map->qdma.int_grp + 4); mtk_w32(eth, eth->soc->rx.irq_done_mask, reg_map->qdma.int_grp + 4);
mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP); mtk_w32(eth, 0x21021000, MTK_FE_INT_GRP);
if (mtk_is_netsys_v3_or_greater(eth)) { if (mtk_is_netsys_v3_or_greater(eth)) {
@ -5048,11 +5048,15 @@ static const struct mtk_soc_data mt2701_data = {
.required_clks = MT7623_CLKS_BITMAP, .required_clks = MT7623_CLKS_BITMAP,
.required_pctl = true, .required_pctl = true,
.version = 1, .version = 1,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma), .desc_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma), .dma_max_len = MTK_TX_DMA_BUF_LEN,
.rx_irq_done_mask = MTK_RX_DONE_INT, .dma_len_offset = 16,
.rx_dma_l4_valid = RX_DMA_L4_VALID, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN, .dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16, .dma_len_offset = 16,
}, },
@ -5068,11 +5072,15 @@ static const struct mtk_soc_data mt7621_data = {
.offload_version = 1, .offload_version = 1,
.hash_offset = 2, .hash_offset = 2,
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma), .desc_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma), .dma_max_len = MTK_TX_DMA_BUF_LEN,
.rx_irq_done_mask = MTK_RX_DONE_INT, .dma_len_offset = 16,
.rx_dma_l4_valid = RX_DMA_L4_VALID, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN, .dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16, .dma_len_offset = 16,
}, },
@ -5090,11 +5098,15 @@ static const struct mtk_soc_data mt7622_data = {
.hash_offset = 2, .hash_offset = 2,
.has_accounting = true, .has_accounting = true,
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma), .desc_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma), .dma_max_len = MTK_TX_DMA_BUF_LEN,
.rx_irq_done_mask = MTK_RX_DONE_INT, .dma_len_offset = 16,
.rx_dma_l4_valid = RX_DMA_L4_VALID, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN, .dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16, .dma_len_offset = 16,
}, },
@ -5111,11 +5123,15 @@ static const struct mtk_soc_data mt7623_data = {
.hash_offset = 2, .hash_offset = 2,
.foe_entry_size = MTK_FOE_ENTRY_V1_SIZE, .foe_entry_size = MTK_FOE_ENTRY_V1_SIZE,
.disable_pll_modes = true, .disable_pll_modes = true,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma), .desc_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma), .dma_max_len = MTK_TX_DMA_BUF_LEN,
.rx_irq_done_mask = MTK_RX_DONE_INT, .dma_len_offset = 16,
.rx_dma_l4_valid = RX_DMA_L4_VALID, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN, .dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16, .dma_len_offset = 16,
}, },
@ -5130,11 +5146,15 @@ static const struct mtk_soc_data mt7629_data = {
.required_pctl = false, .required_pctl = false,
.has_accounting = true, .has_accounting = true,
.version = 1, .version = 1,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma), .desc_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma), .dma_max_len = MTK_TX_DMA_BUF_LEN,
.rx_irq_done_mask = MTK_RX_DONE_INT, .dma_len_offset = 16,
.rx_dma_l4_valid = RX_DMA_L4_VALID, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID,
.dma_max_len = MTK_TX_DMA_BUF_LEN, .dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16, .dma_len_offset = 16,
}, },
@ -5152,14 +5172,18 @@ static const struct mtk_soc_data mt7981_data = {
.hash_offset = 4, .hash_offset = 4,
.has_accounting = true, .has_accounting = true,
.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma_v2), .desc_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
.rx_irq_done_mask = MTK_RX_DONE_INT_V2,
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2, .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = 8, .dma_len_offset = 8,
}, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
}; };
static const struct mtk_soc_data mt7986_data = { static const struct mtk_soc_data mt7986_data = {
@ -5174,14 +5198,18 @@ static const struct mtk_soc_data mt7986_data = {
.hash_offset = 4, .hash_offset = 4,
.has_accounting = true, .has_accounting = true,
.foe_entry_size = MTK_FOE_ENTRY_V2_SIZE, .foe_entry_size = MTK_FOE_ENTRY_V2_SIZE,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma_v2), .desc_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2),
.rx_irq_done_mask = MTK_RX_DONE_INT_V2,
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2, .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = 8, .dma_len_offset = 8,
}, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16,
},
}; };
static const struct mtk_soc_data mt7988_data = { static const struct mtk_soc_data mt7988_data = {
@ -5196,11 +5224,15 @@ static const struct mtk_soc_data mt7988_data = {
.hash_offset = 4, .hash_offset = 4,
.has_accounting = true, .has_accounting = true,
.foe_entry_size = MTK_FOE_ENTRY_V3_SIZE, .foe_entry_size = MTK_FOE_ENTRY_V3_SIZE,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma_v2), .desc_size = sizeof(struct mtk_tx_dma_v2),
.rxd_size = sizeof(struct mtk_rx_dma_v2), .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.rx_irq_done_mask = MTK_RX_DONE_INT_V2, .dma_len_offset = 8,
.rx_dma_l4_valid = RX_DMA_L4_VALID_V2, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma_v2),
.irq_done_mask = MTK_RX_DONE_INT_V2,
.dma_l4_valid = RX_DMA_L4_VALID_V2,
.dma_max_len = MTK_TX_DMA_BUF_LEN_V2, .dma_max_len = MTK_TX_DMA_BUF_LEN_V2,
.dma_len_offset = 8, .dma_len_offset = 8,
}, },
@ -5213,11 +5245,15 @@ static const struct mtk_soc_data rt5350_data = {
.required_clks = MT7628_CLKS_BITMAP, .required_clks = MT7628_CLKS_BITMAP,
.required_pctl = false, .required_pctl = false,
.version = 1, .version = 1,
.txrx = { .tx = {
.txd_size = sizeof(struct mtk_tx_dma), .desc_size = sizeof(struct mtk_tx_dma),
.rxd_size = sizeof(struct mtk_rx_dma), .dma_max_len = MTK_TX_DMA_BUF_LEN,
.rx_irq_done_mask = MTK_RX_DONE_INT, .dma_len_offset = 16,
.rx_dma_l4_valid = RX_DMA_L4_VALID_PDMA, },
.rx = {
.desc_size = sizeof(struct mtk_rx_dma),
.irq_done_mask = MTK_RX_DONE_INT,
.dma_l4_valid = RX_DMA_L4_VALID_PDMA,
.dma_max_len = MTK_TX_DMA_BUF_LEN, .dma_max_len = MTK_TX_DMA_BUF_LEN,
.dma_len_offset = 16, .dma_len_offset = 16,
}, },

View File

@ -327,8 +327,8 @@
/* QDMA descriptor txd3 */ /* QDMA descriptor txd3 */
#define TX_DMA_OWNER_CPU BIT(31) #define TX_DMA_OWNER_CPU BIT(31)
#define TX_DMA_LS0 BIT(30) #define TX_DMA_LS0 BIT(30)
#define TX_DMA_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) #define TX_DMA_PLEN0(x) (((x) & eth->soc->tx.dma_max_len) << eth->soc->tx.dma_len_offset)
#define TX_DMA_PLEN1(x) ((x) & eth->soc->txrx.dma_max_len) #define TX_DMA_PLEN1(x) ((x) & eth->soc->tx.dma_max_len)
#define TX_DMA_SWC BIT(14) #define TX_DMA_SWC BIT(14)
#define TX_DMA_PQID GENMASK(3, 0) #define TX_DMA_PQID GENMASK(3, 0)
#define TX_DMA_ADDR64_MASK GENMASK(3, 0) #define TX_DMA_ADDR64_MASK GENMASK(3, 0)
@ -348,8 +348,8 @@
/* QDMA descriptor rxd2 */ /* QDMA descriptor rxd2 */
#define RX_DMA_DONE BIT(31) #define RX_DMA_DONE BIT(31)
#define RX_DMA_LSO BIT(30) #define RX_DMA_LSO BIT(30)
#define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->txrx.dma_max_len) << eth->soc->txrx.dma_len_offset) #define RX_DMA_PREP_PLEN0(x) (((x) & eth->soc->rx.dma_max_len) << eth->soc->rx.dma_len_offset)
#define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->txrx.dma_len_offset) & eth->soc->txrx.dma_max_len) #define RX_DMA_GET_PLEN0(x) (((x) >> eth->soc->rx.dma_len_offset) & eth->soc->rx.dma_max_len)
#define RX_DMA_VTAG BIT(15) #define RX_DMA_VTAG BIT(15)
#define RX_DMA_ADDR64_MASK GENMASK(3, 0) #define RX_DMA_ADDR64_MASK GENMASK(3, 0)
#if IS_ENABLED(CONFIG_64BIT) #if IS_ENABLED(CONFIG_64BIT)
@ -1153,10 +1153,9 @@ struct mtk_reg_map {
* @foe_entry_size Foe table entry size. * @foe_entry_size Foe table entry size.
* @has_accounting Bool indicating support for accounting of * @has_accounting Bool indicating support for accounting of
* offloaded flows. * offloaded flows.
* @txd_size Tx DMA descriptor size. * @desc_size Tx/Rx DMA descriptor size.
* @rxd_size Rx DMA descriptor size. * @irq_done_mask Rx irq done register mask.
* @rx_irq_done_mask Rx irq done register mask. * @dma_l4_valid Rx DMA valid register mask.
* @rx_dma_l4_valid Rx DMA valid register mask.
* @dma_max_len Max DMA tx/rx buffer length. * @dma_max_len Max DMA tx/rx buffer length.
* @dma_len_offset Tx/Rx DMA length field offset. * @dma_len_offset Tx/Rx DMA length field offset.
*/ */
@ -1174,13 +1173,17 @@ struct mtk_soc_data {
bool has_accounting; bool has_accounting;
bool disable_pll_modes; bool disable_pll_modes;
struct { struct {
u32 txd_size; u32 desc_size;
u32 rxd_size;
u32 rx_irq_done_mask;
u32 rx_dma_l4_valid;
u32 dma_max_len; u32 dma_max_len;
u32 dma_len_offset; u32 dma_len_offset;
} txrx; } tx;
struct {
u32 desc_size;
u32 irq_done_mask;
u32 dma_l4_valid;
u32 dma_max_len;
u32 dma_len_offset;
} rx;
}; };
#define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000) #define MTK_DMA_MONITOR_TIMEOUT msecs_to_jiffies(1000)

View File

@ -969,19 +969,32 @@ static void cmd_work_handler(struct work_struct *work)
bool poll_cmd = ent->polling; bool poll_cmd = ent->polling;
struct mlx5_cmd_layout *lay; struct mlx5_cmd_layout *lay;
struct mlx5_core_dev *dev; struct mlx5_core_dev *dev;
unsigned long cb_timeout; unsigned long timeout;
struct semaphore *sem;
unsigned long flags; unsigned long flags;
int alloc_ret; int alloc_ret;
int cmd_mode; int cmd_mode;
dev = container_of(cmd, struct mlx5_core_dev, cmd);
cb_timeout = msecs_to_jiffies(mlx5_tout_ms(dev, CMD));
complete(&ent->handling); complete(&ent->handling);
sem = ent->page_queue ? &cmd->vars.pages_sem : &cmd->vars.sem;
down(sem); dev = container_of(cmd, struct mlx5_core_dev, cmd);
timeout = msecs_to_jiffies(mlx5_tout_ms(dev, CMD));
if (!ent->page_queue) { if (!ent->page_queue) {
if (down_timeout(&cmd->vars.sem, timeout)) {
mlx5_core_warn(dev, "%s(0x%x) timed out while waiting for a slot.\n",
mlx5_command_str(ent->op), ent->op);
if (ent->callback) {
ent->callback(-EBUSY, ent->context);
mlx5_free_cmd_msg(dev, ent->out);
free_msg(dev, ent->in);
cmd_ent_put(ent);
} else {
ent->ret = -EBUSY;
complete(&ent->done);
}
complete(&ent->slotted);
return;
}
alloc_ret = cmd_alloc_index(cmd, ent); alloc_ret = cmd_alloc_index(cmd, ent);
if (alloc_ret < 0) { if (alloc_ret < 0) {
mlx5_core_err_rl(dev, "failed to allocate command entry\n"); mlx5_core_err_rl(dev, "failed to allocate command entry\n");
@ -994,10 +1007,11 @@ static void cmd_work_handler(struct work_struct *work)
ent->ret = -EAGAIN; ent->ret = -EAGAIN;
complete(&ent->done); complete(&ent->done);
} }
up(sem); up(&cmd->vars.sem);
return; return;
} }
} else { } else {
down(&cmd->vars.pages_sem);
ent->idx = cmd->vars.max_reg_cmds; ent->idx = cmd->vars.max_reg_cmds;
spin_lock_irqsave(&cmd->alloc_lock, flags); spin_lock_irqsave(&cmd->alloc_lock, flags);
clear_bit(ent->idx, &cmd->vars.bitmask); clear_bit(ent->idx, &cmd->vars.bitmask);
@ -1005,6 +1019,8 @@ static void cmd_work_handler(struct work_struct *work)
spin_unlock_irqrestore(&cmd->alloc_lock, flags); spin_unlock_irqrestore(&cmd->alloc_lock, flags);
} }
complete(&ent->slotted);
lay = get_inst(cmd, ent->idx); lay = get_inst(cmd, ent->idx);
ent->lay = lay; ent->lay = lay;
memset(lay, 0, sizeof(*lay)); memset(lay, 0, sizeof(*lay));
@ -1023,7 +1039,7 @@ static void cmd_work_handler(struct work_struct *work)
ent->ts1 = ktime_get_ns(); ent->ts1 = ktime_get_ns();
cmd_mode = cmd->mode; cmd_mode = cmd->mode;
if (ent->callback && schedule_delayed_work(&ent->cb_timeout_work, cb_timeout)) if (ent->callback && schedule_delayed_work(&ent->cb_timeout_work, timeout))
cmd_ent_get(ent); cmd_ent_get(ent);
set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state); set_bit(MLX5_CMD_ENT_STATE_PENDING_COMP, &ent->state);
@ -1143,6 +1159,9 @@ static int wait_func(struct mlx5_core_dev *dev, struct mlx5_cmd_work_ent *ent)
ent->ret = -ECANCELED; ent->ret = -ECANCELED;
goto out_err; goto out_err;
} }
wait_for_completion(&ent->slotted);
if (cmd->mode == CMD_MODE_POLLING || ent->polling) if (cmd->mode == CMD_MODE_POLLING || ent->polling)
wait_for_completion(&ent->done); wait_for_completion(&ent->done);
else if (!wait_for_completion_timeout(&ent->done, timeout)) else if (!wait_for_completion_timeout(&ent->done, timeout))
@ -1157,6 +1176,9 @@ out_err:
} else if (err == -ECANCELED) { } else if (err == -ECANCELED) {
mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n", mlx5_core_warn(dev, "%s(0x%x) canceled on out of queue timeout.\n",
mlx5_command_str(ent->op), ent->op); mlx5_command_str(ent->op), ent->op);
} else if (err == -EBUSY) {
mlx5_core_warn(dev, "%s(0x%x) timeout while waiting for command semaphore.\n",
mlx5_command_str(ent->op), ent->op);
} }
mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n", mlx5_core_dbg(dev, "err %d, delivery status %s(%d)\n",
err, deliv_status_to_str(ent->status), ent->status); err, deliv_status_to_str(ent->status), ent->status);
@ -1208,6 +1230,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
ent->polling = force_polling; ent->polling = force_polling;
init_completion(&ent->handling); init_completion(&ent->handling);
init_completion(&ent->slotted);
if (!callback) if (!callback)
init_completion(&ent->done); init_completion(&ent->done);
@ -1225,7 +1248,7 @@ static int mlx5_cmd_invoke(struct mlx5_core_dev *dev, struct mlx5_cmd_msg *in,
return 0; /* mlx5_cmd_comp_handler() will put(ent) */ return 0; /* mlx5_cmd_comp_handler() will put(ent) */
err = wait_func(dev, ent); err = wait_func(dev, ent);
if (err == -ETIMEDOUT || err == -ECANCELED) if (err == -ETIMEDOUT || err == -ECANCELED || err == -EBUSY)
goto out_free; goto out_free;
ds = ent->ts2 - ent->ts1; ds = ent->ts2 - ent->ts1;
@ -1611,6 +1634,9 @@ static int cmd_comp_notifier(struct notifier_block *nb,
dev = container_of(cmd, struct mlx5_core_dev, cmd); dev = container_of(cmd, struct mlx5_core_dev, cmd);
eqe = data; eqe = data;
if (dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR)
return NOTIFY_DONE;
mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector), false); mlx5_cmd_comp_handler(dev, be32_to_cpu(eqe->data.cmd.vector), false);
return NOTIFY_OK; return NOTIFY_OK;

View File

@ -6194,7 +6194,7 @@ static int mlx5e_resume(struct auxiliary_device *adev)
return 0; return 0;
} }
static int _mlx5e_suspend(struct auxiliary_device *adev) static int _mlx5e_suspend(struct auxiliary_device *adev, bool pre_netdev_reg)
{ {
struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev); struct mlx5e_dev *mlx5e_dev = auxiliary_get_drvdata(adev);
struct mlx5e_priv *priv = mlx5e_dev->priv; struct mlx5e_priv *priv = mlx5e_dev->priv;
@ -6203,7 +6203,7 @@ static int _mlx5e_suspend(struct auxiliary_device *adev)
struct mlx5_core_dev *pos; struct mlx5_core_dev *pos;
int i; int i;
if (!netif_device_present(netdev)) { if (!pre_netdev_reg && !netif_device_present(netdev)) {
if (test_bit(MLX5E_STATE_DESTROYING, &priv->state)) if (test_bit(MLX5E_STATE_DESTROYING, &priv->state))
mlx5_sd_for_each_dev(i, mdev, pos) mlx5_sd_for_each_dev(i, mdev, pos)
mlx5e_destroy_mdev_resources(pos); mlx5e_destroy_mdev_resources(pos);
@ -6226,7 +6226,7 @@ static int mlx5e_suspend(struct auxiliary_device *adev, pm_message_t state)
actual_adev = mlx5_sd_get_adev(mdev, adev, edev->idx); actual_adev = mlx5_sd_get_adev(mdev, adev, edev->idx);
if (actual_adev) if (actual_adev)
err = _mlx5e_suspend(actual_adev); err = _mlx5e_suspend(actual_adev, false);
mlx5_sd_cleanup(mdev); mlx5_sd_cleanup(mdev);
return err; return err;
@ -6293,7 +6293,7 @@ static int _mlx5e_probe(struct auxiliary_device *adev)
return 0; return 0;
err_resume: err_resume:
_mlx5e_suspend(adev); _mlx5e_suspend(adev, true);
err_profile_cleanup: err_profile_cleanup:
profile->cleanup(priv); profile->cleanup(priv);
err_destroy_netdev: err_destroy_netdev:
@ -6333,7 +6333,7 @@ static void _mlx5e_remove(struct auxiliary_device *adev)
mlx5_core_uplink_netdev_set(mdev, NULL); mlx5_core_uplink_netdev_set(mdev, NULL);
mlx5e_dcbnl_delete_app(priv); mlx5e_dcbnl_delete_app(priv);
unregister_netdev(priv->netdev); unregister_netdev(priv->netdev);
_mlx5e_suspend(adev); _mlx5e_suspend(adev, false);
priv->profile->cleanup(priv); priv->profile->cleanup(priv);
mlx5e_destroy_netdev(priv); mlx5e_destroy_netdev(priv);
mlx5e_devlink_port_unregister(mlx5e_dev); mlx5e_devlink_port_unregister(mlx5e_dev);

View File

@ -840,7 +840,7 @@ int mlx5_eswitch_offloads_single_fdb_add_one(struct mlx5_eswitch *master_esw,
struct mlx5_eswitch *slave_esw, int max_slaves); struct mlx5_eswitch *slave_esw, int max_slaves);
void mlx5_eswitch_offloads_single_fdb_del_one(struct mlx5_eswitch *master_esw, void mlx5_eswitch_offloads_single_fdb_del_one(struct mlx5_eswitch *master_esw,
struct mlx5_eswitch *slave_esw); struct mlx5_eswitch *slave_esw);
int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw); int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw);
bool mlx5_eswitch_block_encap(struct mlx5_core_dev *dev); bool mlx5_eswitch_block_encap(struct mlx5_core_dev *dev);
void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev); void mlx5_eswitch_unblock_encap(struct mlx5_core_dev *dev);
@ -932,7 +932,7 @@ mlx5_eswitch_offloads_single_fdb_del_one(struct mlx5_eswitch *master_esw,
static inline int mlx5_eswitch_get_npeers(struct mlx5_eswitch *esw) { return 0; } static inline int mlx5_eswitch_get_npeers(struct mlx5_eswitch *esw) { return 0; }
static inline int static inline int
mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw) mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
{ {
return 0; return 0;
} }

View File

@ -2505,6 +2505,16 @@ void esw_offloads_cleanup(struct mlx5_eswitch *esw)
esw_offloads_cleanup_reps(esw); esw_offloads_cleanup_reps(esw);
} }
static int __esw_offloads_load_rep(struct mlx5_eswitch *esw,
struct mlx5_eswitch_rep *rep, u8 rep_type)
{
if (atomic_cmpxchg(&rep->rep_data[rep_type].state,
REP_REGISTERED, REP_LOADED) == REP_REGISTERED)
return esw->offloads.rep_ops[rep_type]->load(esw->dev, rep);
return 0;
}
static void __esw_offloads_unload_rep(struct mlx5_eswitch *esw, static void __esw_offloads_unload_rep(struct mlx5_eswitch *esw,
struct mlx5_eswitch_rep *rep, u8 rep_type) struct mlx5_eswitch_rep *rep, u8 rep_type)
{ {
@ -2529,13 +2539,11 @@ static int mlx5_esw_offloads_rep_load(struct mlx5_eswitch *esw, u16 vport_num)
int err; int err;
rep = mlx5_eswitch_get_rep(esw, vport_num); rep = mlx5_eswitch_get_rep(esw, vport_num);
for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) for (rep_type = 0; rep_type < NUM_REP_TYPES; rep_type++) {
if (atomic_cmpxchg(&rep->rep_data[rep_type].state, err = __esw_offloads_load_rep(esw, rep, rep_type);
REP_REGISTERED, REP_LOADED) == REP_REGISTERED) { if (err)
err = esw->offloads.rep_ops[rep_type]->load(esw->dev, rep); goto err_reps;
if (err) }
goto err_reps;
}
return 0; return 0;
@ -3280,7 +3288,7 @@ static void esw_destroy_offloads_acl_tables(struct mlx5_eswitch *esw)
esw_vport_destroy_offloads_acl_tables(esw, vport); esw_vport_destroy_offloads_acl_tables(esw, vport);
} }
int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw) int mlx5_eswitch_reload_ib_reps(struct mlx5_eswitch *esw)
{ {
struct mlx5_eswitch_rep *rep; struct mlx5_eswitch_rep *rep;
unsigned long i; unsigned long i;
@ -3293,13 +3301,13 @@ int mlx5_eswitch_reload_reps(struct mlx5_eswitch *esw)
if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED) if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED)
return 0; return 0;
ret = mlx5_esw_offloads_rep_load(esw, MLX5_VPORT_UPLINK); ret = __esw_offloads_load_rep(esw, rep, REP_IB);
if (ret) if (ret)
return ret; return ret;
mlx5_esw_for_each_rep(esw, i, rep) { mlx5_esw_for_each_rep(esw, i, rep) {
if (atomic_read(&rep->rep_data[REP_ETH].state) == REP_LOADED) if (atomic_read(&rep->rep_data[REP_ETH].state) == REP_LOADED)
mlx5_esw_offloads_rep_load(esw, rep->vport); __esw_offloads_load_rep(esw, rep, REP_IB);
} }
return 0; return 0;

View File

@ -811,7 +811,7 @@ void mlx5_disable_lag(struct mlx5_lag *ldev)
if (shared_fdb) if (shared_fdb)
for (i = 0; i < ldev->ports; i++) for (i = 0; i < ldev->ports; i++)
if (!(ldev->pf[i].dev->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV)) if (!(ldev->pf[i].dev->priv.flags & MLX5_PRIV_FLAGS_DISABLE_ALL_ADEV))
mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch); mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
} }
static bool mlx5_shared_fdb_supported(struct mlx5_lag *ldev) static bool mlx5_shared_fdb_supported(struct mlx5_lag *ldev)
@ -919,7 +919,7 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
mlx5_rescan_drivers_locked(dev0); mlx5_rescan_drivers_locked(dev0);
for (i = 0; i < ldev->ports; i++) { for (i = 0; i < ldev->ports; i++) {
err = mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch); err = mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
if (err) if (err)
break; break;
} }
@ -930,7 +930,7 @@ static void mlx5_do_bond(struct mlx5_lag *ldev)
mlx5_deactivate_lag(ldev); mlx5_deactivate_lag(ldev);
mlx5_lag_add_devices(ldev); mlx5_lag_add_devices(ldev);
for (i = 0; i < ldev->ports; i++) for (i = 0; i < ldev->ports; i++)
mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch); mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
mlx5_core_err(dev0, "Failed to enable lag\n"); mlx5_core_err(dev0, "Failed to enable lag\n");
return; return;
} }

View File

@ -99,7 +99,7 @@ static int enable_mpesw(struct mlx5_lag *ldev)
dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV; dev0->priv.flags &= ~MLX5_PRIV_FLAGS_DISABLE_IB_ADEV;
mlx5_rescan_drivers_locked(dev0); mlx5_rescan_drivers_locked(dev0);
for (i = 0; i < ldev->ports; i++) { for (i = 0; i < ldev->ports; i++) {
err = mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch); err = mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
if (err) if (err)
goto err_rescan_drivers; goto err_rescan_drivers;
} }
@ -113,7 +113,7 @@ err_rescan_drivers:
err_add_devices: err_add_devices:
mlx5_lag_add_devices(ldev); mlx5_lag_add_devices(ldev);
for (i = 0; i < ldev->ports; i++) for (i = 0; i < ldev->ports; i++)
mlx5_eswitch_reload_reps(ldev->pf[i].dev->priv.eswitch); mlx5_eswitch_reload_ib_reps(ldev->pf[i].dev->priv.eswitch);
mlx5_mpesw_metadata_cleanup(ldev); mlx5_mpesw_metadata_cleanup(ldev);
return err; return err;
} }

View File

@ -1680,6 +1680,8 @@ int mlx5_init_one_light(struct mlx5_core_dev *dev)
struct devlink *devlink = priv_to_devlink(dev); struct devlink *devlink = priv_to_devlink(dev);
int err; int err;
devl_lock(devlink);
devl_register(devlink);
dev->state = MLX5_DEVICE_STATE_UP; dev->state = MLX5_DEVICE_STATE_UP;
err = mlx5_function_enable(dev, true, mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT)); err = mlx5_function_enable(dev, true, mlx5_tout_ms(dev, FW_PRE_INIT_TIMEOUT));
if (err) { if (err) {
@ -1693,27 +1695,21 @@ int mlx5_init_one_light(struct mlx5_core_dev *dev)
goto query_hca_caps_err; goto query_hca_caps_err;
} }
devl_lock(devlink);
devl_register(devlink);
err = mlx5_devlink_params_register(priv_to_devlink(dev)); err = mlx5_devlink_params_register(priv_to_devlink(dev));
if (err) { if (err) {
mlx5_core_warn(dev, "mlx5_devlink_param_reg err = %d\n", err); mlx5_core_warn(dev, "mlx5_devlink_param_reg err = %d\n", err);
goto params_reg_err; goto query_hca_caps_err;
} }
devl_unlock(devlink); devl_unlock(devlink);
return 0; return 0;
params_reg_err:
devl_unregister(devlink);
devl_unlock(devlink);
query_hca_caps_err: query_hca_caps_err:
devl_unregister(devlink);
devl_unlock(devlink);
mlx5_function_disable(dev, true); mlx5_function_disable(dev, true);
out: out:
dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR; dev->state = MLX5_DEVICE_STATE_INTERNAL_ERROR;
devl_unregister(devlink);
devl_unlock(devlink);
return err; return err;
} }

View File

@ -60,6 +60,13 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
goto remap_err; goto remap_err;
} }
/* Peer devlink logic expects to work on unregistered devlink instance. */
err = mlx5_core_peer_devlink_set(sf_dev, devlink);
if (err) {
mlx5_core_warn(mdev, "mlx5_core_peer_devlink_set err=%d\n", err);
goto peer_devlink_set_err;
}
if (MLX5_ESWITCH_MANAGER(sf_dev->parent_mdev)) if (MLX5_ESWITCH_MANAGER(sf_dev->parent_mdev))
err = mlx5_init_one_light(mdev); err = mlx5_init_one_light(mdev);
else else
@ -69,20 +76,10 @@ static int mlx5_sf_dev_probe(struct auxiliary_device *adev, const struct auxilia
goto init_one_err; goto init_one_err;
} }
err = mlx5_core_peer_devlink_set(sf_dev, devlink);
if (err) {
mlx5_core_warn(mdev, "mlx5_core_peer_devlink_set err=%d\n", err);
goto peer_devlink_set_err;
}
return 0; return 0;
peer_devlink_set_err:
if (mlx5_dev_is_lightweight(sf_dev->mdev))
mlx5_uninit_one_light(sf_dev->mdev);
else
mlx5_uninit_one(sf_dev->mdev);
init_one_err: init_one_err:
peer_devlink_set_err:
iounmap(mdev->iseg); iounmap(mdev->iseg);
remap_err: remap_err:
mlx5_mdev_uninit(mdev); mlx5_mdev_uninit(mdev);

View File

@ -156,8 +156,8 @@ static inline void mcf_outsw(void *a, unsigned char *p, int l)
writew(*wp++, a); writew(*wp++, a);
} }
#define SMC_inw(a, r) _swapw(readw((a) + (r))) #define SMC_inw(a, r) ioread16be((a) + (r))
#define SMC_outw(lp, v, a, r) writew(_swapw(v), (a) + (r)) #define SMC_outw(lp, v, a, r) iowrite16be(v, (a) + (r))
#define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l) #define SMC_insw(a, r, p, l) mcf_insw(a + r, p, l)
#define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l) #define SMC_outsw(a, r, p, l) mcf_outsw(a + r, p, l)

View File

@ -949,17 +949,6 @@ static irqreturn_t gem_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
#ifdef CONFIG_NET_POLL_CONTROLLER
static void gem_poll_controller(struct net_device *dev)
{
struct gem *gp = netdev_priv(dev);
disable_irq(gp->pdev->irq);
gem_interrupt(gp->pdev->irq, dev);
enable_irq(gp->pdev->irq);
}
#endif
static void gem_tx_timeout(struct net_device *dev, unsigned int txqueue) static void gem_tx_timeout(struct net_device *dev, unsigned int txqueue)
{ {
struct gem *gp = netdev_priv(dev); struct gem *gp = netdev_priv(dev);
@ -2839,9 +2828,6 @@ static const struct net_device_ops gem_netdev_ops = {
.ndo_change_mtu = gem_change_mtu, .ndo_change_mtu = gem_change_mtu,
.ndo_validate_addr = eth_validate_addr, .ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = gem_set_mac_address, .ndo_set_mac_address = gem_set_mac_address,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = gem_poll_controller,
#endif
}; };
static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) static int gem_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)

View File

@ -5189,7 +5189,8 @@ static int lan8841_suspend(struct phy_device *phydev)
struct kszphy_priv *priv = phydev->priv; struct kszphy_priv *priv = phydev->priv;
struct kszphy_ptp_priv *ptp_priv = &priv->ptp_priv; struct kszphy_ptp_priv *ptp_priv = &priv->ptp_priv;
ptp_cancel_worker_sync(ptp_priv->ptp_clock); if (ptp_priv->ptp_clock)
ptp_cancel_worker_sync(ptp_priv->ptp_clock);
return genphy_suspend(phydev); return genphy_suspend(phydev);
} }

View File

@ -174,6 +174,7 @@ struct ax88179_data {
u32 wol_supported; u32 wol_supported;
u32 wolopts; u32 wolopts;
u8 disconnecting; u8 disconnecting;
u8 initialized;
}; };
struct ax88179_int_data { struct ax88179_int_data {
@ -1675,6 +1676,18 @@ static int ax88179_reset(struct usbnet *dev)
return 0; return 0;
} }
static int ax88179_net_reset(struct usbnet *dev)
{
struct ax88179_data *ax179_data = dev->driver_priv;
if (ax179_data->initialized)
ax88179_reset(dev);
else
ax179_data->initialized = 1;
return 0;
}
static int ax88179_stop(struct usbnet *dev) static int ax88179_stop(struct usbnet *dev)
{ {
u16 tmp16; u16 tmp16;
@ -1694,6 +1707,7 @@ static const struct driver_info ax88179_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1706,6 +1720,7 @@ static const struct driver_info ax88178a_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1718,7 +1733,7 @@ static const struct driver_info cypress_GX3_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1731,7 +1746,7 @@ static const struct driver_info dlink_dub1312_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1744,7 +1759,7 @@ static const struct driver_info sitecom_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1757,7 +1772,7 @@ static const struct driver_info samsung_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1770,7 +1785,7 @@ static const struct driver_info lenovo_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1783,7 +1798,7 @@ static const struct driver_info belkin_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1796,7 +1811,7 @@ static const struct driver_info toshiba_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1809,7 +1824,7 @@ static const struct driver_info mct_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1822,7 +1837,7 @@ static const struct driver_info at_umc2000_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1835,7 +1850,7 @@ static const struct driver_info at_umc200_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,
@ -1848,7 +1863,7 @@ static const struct driver_info at_umc2000sp_info = {
.unbind = ax88179_unbind, .unbind = ax88179_unbind,
.status = ax88179_status, .status = ax88179_status,
.link_reset = ax88179_link_reset, .link_reset = ax88179_link_reset,
.reset = ax88179_reset, .reset = ax88179_net_reset,
.stop = ax88179_stop, .stop = ax88179_stop,
.flags = FLAG_ETHER | FLAG_FRAMING_AX, .flags = FLAG_ETHER | FLAG_FRAMING_AX,
.rx_fixup = ax88179_rx_fixup, .rx_fixup = ax88179_rx_fixup,

View File

@ -4562,7 +4562,7 @@ static int ptp_ocp_dpll_direction_set(const struct dpll_pin *pin,
return -EOPNOTSUPP; return -EOPNOTSUPP;
mode = direction == DPLL_PIN_DIRECTION_INPUT ? mode = direction == DPLL_PIN_DIRECTION_INPUT ?
SMA_MODE_IN : SMA_MODE_OUT; SMA_MODE_IN : SMA_MODE_OUT;
return ptp_ocp_sma_store_val(bp, 0, mode, sma_nr); return ptp_ocp_sma_store_val(bp, 0, mode, sma_nr + 1);
} }
static int ptp_ocp_dpll_frequency_set(const struct dpll_pin *pin, static int ptp_ocp_dpll_frequency_set(const struct dpll_pin *pin,
@ -4583,7 +4583,7 @@ static int ptp_ocp_dpll_frequency_set(const struct dpll_pin *pin,
tbl = bp->sma_op->tbl[sma->mode]; tbl = bp->sma_op->tbl[sma->mode];
for (i = 0; tbl[i].name; i++) for (i = 0; tbl[i].name; i++)
if (tbl[i].frequency == frequency) if (tbl[i].frequency == frequency)
return ptp_ocp_sma_store_val(bp, i, sma->mode, sma_nr); return ptp_ocp_sma_store_val(bp, i, sma->mode, sma_nr + 1);
return -EINVAL; return -EINVAL;
} }
@ -4600,7 +4600,7 @@ static int ptp_ocp_dpll_frequency_get(const struct dpll_pin *pin,
u32 val; u32 val;
int i; int i;
val = bp->sma_op->get(bp, sma_nr); val = bp->sma_op->get(bp, sma_nr + 1);
tbl = bp->sma_op->tbl[sma->mode]; tbl = bp->sma_op->tbl[sma->mode];
for (i = 0; tbl[i].name; i++) for (i = 0; tbl[i].name; i++)
if (val == tbl[i].value) { if (val == tbl[i].value) {

View File

@ -862,6 +862,7 @@ struct mlx5_cmd_work_ent {
void *context; void *context;
int idx; int idx;
struct completion handling; struct completion handling;
struct completion slotted;
struct completion done; struct completion done;
struct mlx5_cmd *cmd; struct mlx5_cmd *cmd;
struct work_struct work; struct work_struct work;

View File

@ -218,7 +218,7 @@ typedef struct {
struct ctl_table; struct ctl_table;
typedef struct ax25_dev { typedef struct ax25_dev {
struct ax25_dev *next; struct list_head list;
struct net_device *dev; struct net_device *dev;
netdevice_tracker dev_tracker; netdevice_tracker dev_tracker;
@ -332,7 +332,6 @@ int ax25_addr_size(const ax25_digi *);
void ax25_digi_invert(const ax25_digi *, ax25_digi *); void ax25_digi_invert(const ax25_digi *, ax25_digi *);
/* ax25_dev.c */ /* ax25_dev.c */
extern ax25_dev *ax25_dev_list;
extern spinlock_t ax25_dev_lock; extern spinlock_t ax25_dev_lock;
#if IS_ENABLED(CONFIG_AX25) #if IS_ENABLED(CONFIG_AX25)

View File

@ -183,7 +183,8 @@ int cipso_v4_getattr(const unsigned char *cipso,
struct netlbl_lsm_secattr *secattr); struct netlbl_lsm_secattr *secattr);
int cipso_v4_sock_setattr(struct sock *sk, int cipso_v4_sock_setattr(struct sock *sk,
const struct cipso_v4_doi *doi_def, const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr); const struct netlbl_lsm_secattr *secattr,
bool sk_locked);
void cipso_v4_sock_delattr(struct sock *sk); void cipso_v4_sock_delattr(struct sock *sk);
int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr); int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
int cipso_v4_req_setattr(struct request_sock *req, int cipso_v4_req_setattr(struct request_sock *req,
@ -214,7 +215,8 @@ static inline int cipso_v4_getattr(const unsigned char *cipso,
static inline int cipso_v4_sock_setattr(struct sock *sk, static inline int cipso_v4_sock_setattr(struct sock *sk,
const struct cipso_v4_doi *doi_def, const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr) const struct netlbl_lsm_secattr *secattr,
bool sk_locked)
{ {
return -ENOSYS; return -ENOSYS;
} }

View File

@ -470,7 +470,8 @@ void netlbl_bitmap_setbit(unsigned char *bitmap, u32 bit, u8 state);
int netlbl_enabled(void); int netlbl_enabled(void);
int netlbl_sock_setattr(struct sock *sk, int netlbl_sock_setattr(struct sock *sk,
u16 family, u16 family,
const struct netlbl_lsm_secattr *secattr); const struct netlbl_lsm_secattr *secattr,
bool sk_locked);
void netlbl_sock_delattr(struct sock *sk); void netlbl_sock_delattr(struct sock *sk);
int netlbl_sock_getattr(struct sock *sk, int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr); struct netlbl_lsm_secattr *secattr);
@ -487,6 +488,7 @@ int netlbl_skbuff_getattr(const struct sk_buff *skb,
u16 family, u16 family,
struct netlbl_lsm_secattr *secattr); struct netlbl_lsm_secattr *secattr);
void netlbl_skbuff_err(struct sk_buff *skb, u16 family, int error, int gateway); void netlbl_skbuff_err(struct sk_buff *skb, u16 family, int error, int gateway);
bool netlbl_sk_lock_check(struct sock *sk);
/* /*
* LSM label mapping cache operations * LSM label mapping cache operations
@ -614,7 +616,8 @@ static inline int netlbl_enabled(void)
} }
static inline int netlbl_sock_setattr(struct sock *sk, static inline int netlbl_sock_setattr(struct sock *sk,
u16 family, u16 family,
const struct netlbl_lsm_secattr *secattr) const struct netlbl_lsm_secattr *secattr,
bool sk_locked)
{ {
return -ENOSYS; return -ENOSYS;
} }
@ -673,6 +676,11 @@ static inline struct audit_buffer *netlbl_audit_start(int type,
{ {
return NULL; return NULL;
} }
static inline bool netlbl_sk_lock_check(struct sock *sk)
{
return true;
}
#endif /* CONFIG_NETLABEL */ #endif /* CONFIG_NETLABEL */
const struct netlbl_calipso_ops * const struct netlbl_calipso_ops *

View File

@ -3998,6 +3998,11 @@ static int bpf_prog_attach_check_attach_type(const struct bpf_prog *prog,
* check permissions at attach time. * check permissions at attach time.
*/ */
return -EPERM; return -EPERM;
ptype = attach_type_to_prog_type(attach_type);
if (prog->type != ptype)
return -EINVAL;
return prog->enforce_expected_attach_type && return prog->enforce_expected_attach_type &&
prog->expected_attach_type != attach_type ? prog->expected_attach_type != attach_type ?
-EINVAL : 0; -EINVAL : 0;

View File

@ -22,11 +22,12 @@
#include <net/sock.h> #include <net/sock.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/list.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h> #include <linux/init.h>
ax25_dev *ax25_dev_list; static LIST_HEAD(ax25_dev_list);
DEFINE_SPINLOCK(ax25_dev_lock); DEFINE_SPINLOCK(ax25_dev_lock);
ax25_dev *ax25_addr_ax25dev(ax25_address *addr) ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
@ -34,10 +35,11 @@ ax25_dev *ax25_addr_ax25dev(ax25_address *addr)
ax25_dev *ax25_dev, *res = NULL; ax25_dev *ax25_dev, *res = NULL;
spin_lock_bh(&ax25_dev_lock); spin_lock_bh(&ax25_dev_lock);
for (ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) list_for_each_entry(ax25_dev, &ax25_dev_list, list)
if (ax25cmp(addr, (const ax25_address *)ax25_dev->dev->dev_addr) == 0) { if (ax25cmp(addr, (const ax25_address *)ax25_dev->dev->dev_addr) == 0) {
res = ax25_dev; res = ax25_dev;
ax25_dev_hold(ax25_dev); ax25_dev_hold(ax25_dev);
break;
} }
spin_unlock_bh(&ax25_dev_lock); spin_unlock_bh(&ax25_dev_lock);
@ -59,7 +61,6 @@ void ax25_dev_device_up(struct net_device *dev)
} }
refcount_set(&ax25_dev->refcount, 1); refcount_set(&ax25_dev->refcount, 1);
dev->ax25_ptr = ax25_dev;
ax25_dev->dev = dev; ax25_dev->dev = dev;
netdev_hold(dev, &ax25_dev->dev_tracker, GFP_KERNEL); netdev_hold(dev, &ax25_dev->dev_tracker, GFP_KERNEL);
ax25_dev->forward = NULL; ax25_dev->forward = NULL;
@ -88,10 +89,9 @@ void ax25_dev_device_up(struct net_device *dev)
#endif #endif
spin_lock_bh(&ax25_dev_lock); spin_lock_bh(&ax25_dev_lock);
ax25_dev->next = ax25_dev_list; list_add(&ax25_dev->list, &ax25_dev_list);
ax25_dev_list = ax25_dev; dev->ax25_ptr = ax25_dev;
spin_unlock_bh(&ax25_dev_lock); spin_unlock_bh(&ax25_dev_lock);
ax25_dev_hold(ax25_dev);
ax25_register_dev_sysctl(ax25_dev); ax25_register_dev_sysctl(ax25_dev);
} }
@ -114,32 +114,19 @@ void ax25_dev_device_down(struct net_device *dev)
/* /*
* Remove any packet forwarding that points to this device. * Remove any packet forwarding that points to this device.
*/ */
for (s = ax25_dev_list; s != NULL; s = s->next) list_for_each_entry(s, &ax25_dev_list, list)
if (s->forward == dev) if (s->forward == dev)
s->forward = NULL; s->forward = NULL;
if ((s = ax25_dev_list) == ax25_dev) { list_for_each_entry(s, &ax25_dev_list, list) {
ax25_dev_list = s->next; if (s == ax25_dev) {
goto unlock_put; list_del(&s->list);
} break;
while (s != NULL && s->next != NULL) {
if (s->next == ax25_dev) {
s->next = ax25_dev->next;
goto unlock_put;
} }
s = s->next;
} }
spin_unlock_bh(&ax25_dev_lock);
dev->ax25_ptr = NULL;
ax25_dev_put(ax25_dev);
return;
unlock_put:
spin_unlock_bh(&ax25_dev_lock);
ax25_dev_put(ax25_dev);
dev->ax25_ptr = NULL; dev->ax25_ptr = NULL;
spin_unlock_bh(&ax25_dev_lock);
netdev_put(dev, &ax25_dev->dev_tracker); netdev_put(dev, &ax25_dev->dev_tracker);
ax25_dev_put(ax25_dev); ax25_dev_put(ax25_dev);
} }
@ -203,16 +190,13 @@ struct net_device *ax25_fwd_dev(struct net_device *dev)
*/ */
void __exit ax25_dev_free(void) void __exit ax25_dev_free(void)
{ {
ax25_dev *s, *ax25_dev; ax25_dev *s, *n;
spin_lock_bh(&ax25_dev_lock); spin_lock_bh(&ax25_dev_lock);
ax25_dev = ax25_dev_list; list_for_each_entry_safe(s, n, &ax25_dev_list, list) {
while (ax25_dev != NULL) { netdev_put(s->dev, &s->dev_tracker);
s = ax25_dev; list_del(&s->list);
netdev_put(ax25_dev->dev, &ax25_dev->dev_tracker);
ax25_dev = ax25_dev->next;
kfree(s); kfree(s);
} }
ax25_dev_list = NULL;
spin_unlock_bh(&ax25_dev_lock); spin_unlock_bh(&ax25_dev_lock);
} }

View File

@ -1815,6 +1815,7 @@ static int cipso_v4_genopt(unsigned char *buf, u32 buf_len,
* @sk: the socket * @sk: the socket
* @doi_def: the CIPSO DOI to use * @doi_def: the CIPSO DOI to use
* @secattr: the specific security attributes of the socket * @secattr: the specific security attributes of the socket
* @sk_locked: true if caller holds the socket lock
* *
* Description: * Description:
* Set the CIPSO option on the given socket using the DOI definition and * Set the CIPSO option on the given socket using the DOI definition and
@ -1826,7 +1827,8 @@ static int cipso_v4_genopt(unsigned char *buf, u32 buf_len,
*/ */
int cipso_v4_sock_setattr(struct sock *sk, int cipso_v4_sock_setattr(struct sock *sk,
const struct cipso_v4_doi *doi_def, const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr) const struct netlbl_lsm_secattr *secattr,
bool sk_locked)
{ {
int ret_val = -EPERM; int ret_val = -EPERM;
unsigned char *buf = NULL; unsigned char *buf = NULL;
@ -1876,8 +1878,7 @@ int cipso_v4_sock_setattr(struct sock *sk,
sk_inet = inet_sk(sk); sk_inet = inet_sk(sk);
old = rcu_dereference_protected(sk_inet->inet_opt, old = rcu_dereference_protected(sk_inet->inet_opt, sk_locked);
lockdep_sock_is_held(sk));
if (inet_test_bit(IS_ICSK, sk)) { if (inet_test_bit(IS_ICSK, sk)) {
sk_conn = inet_csk(sk); sk_conn = inet_csk(sk);
if (old) if (old)

View File

@ -1688,6 +1688,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
struct nlmsghdr *nlh; struct nlmsghdr *nlh;
unsigned long tstamp; unsigned long tstamp;
u32 preferred, valid; u32 preferred, valid;
u32 flags;
nlh = nlmsg_put(skb, args->portid, args->seq, args->event, sizeof(*ifm), nlh = nlmsg_put(skb, args->portid, args->seq, args->event, sizeof(*ifm),
args->flags); args->flags);
@ -1697,7 +1698,13 @@ static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
ifm = nlmsg_data(nlh); ifm = nlmsg_data(nlh);
ifm->ifa_family = AF_INET; ifm->ifa_family = AF_INET;
ifm->ifa_prefixlen = ifa->ifa_prefixlen; ifm->ifa_prefixlen = ifa->ifa_prefixlen;
ifm->ifa_flags = READ_ONCE(ifa->ifa_flags);
flags = READ_ONCE(ifa->ifa_flags);
/* Warning : ifm->ifa_flags is an __u8, it holds only 8 bits.
* The 32bit value is given in IFA_FLAGS attribute.
*/
ifm->ifa_flags = (__u8)flags;
ifm->ifa_scope = ifa->ifa_scope; ifm->ifa_scope = ifa->ifa_scope;
ifm->ifa_index = ifa->ifa_dev->dev->ifindex; ifm->ifa_index = ifa->ifa_dev->dev->ifindex;
@ -1706,7 +1713,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
goto nla_put_failure; goto nla_put_failure;
tstamp = READ_ONCE(ifa->ifa_tstamp); tstamp = READ_ONCE(ifa->ifa_tstamp);
if (!(ifm->ifa_flags & IFA_F_PERMANENT)) { if (!(flags & IFA_F_PERMANENT)) {
preferred = READ_ONCE(ifa->ifa_preferred_lft); preferred = READ_ONCE(ifa->ifa_preferred_lft);
valid = READ_ONCE(ifa->ifa_valid_lft); valid = READ_ONCE(ifa->ifa_valid_lft);
if (preferred != INFINITY_LIFE_TIME) { if (preferred != INFINITY_LIFE_TIME) {
@ -1737,7 +1744,7 @@ static int inet_fill_ifaddr(struct sk_buff *skb, const struct in_ifaddr *ifa,
nla_put_string(skb, IFA_LABEL, ifa->ifa_label)) || nla_put_string(skb, IFA_LABEL, ifa->ifa_label)) ||
(ifa->ifa_proto && (ifa->ifa_proto &&
nla_put_u8(skb, IFA_PROTO, ifa->ifa_proto)) || nla_put_u8(skb, IFA_PROTO, ifa->ifa_proto)) ||
nla_put_u32(skb, IFA_FLAGS, ifm->ifa_flags) || nla_put_u32(skb, IFA_FLAGS, flags) ||
(ifa->ifa_rt_priority && (ifa->ifa_rt_priority &&
nla_put_u32(skb, IFA_RT_PRIORITY, ifa->ifa_rt_priority)) || nla_put_u32(skb, IFA_RT_PRIORITY, ifa->ifa_rt_priority)) ||
put_cacheinfo(skb, READ_ONCE(ifa->ifa_cstamp), tstamp, put_cacheinfo(skb, READ_ONCE(ifa->ifa_cstamp), tstamp,

View File

@ -551,6 +551,8 @@ out_unregister_iptun:
#endif #endif
#ifdef CONFIG_IPV6_SEG6_LWTUNNEL #ifdef CONFIG_IPV6_SEG6_LWTUNNEL
out_unregister_genl: out_unregister_genl:
#endif
#if IS_ENABLED(CONFIG_IPV6_SEG6_LWTUNNEL) || IS_ENABLED(CONFIG_IPV6_SEG6_HMAC)
genl_unregister_family(&seg6_genl_family); genl_unregister_family(&seg6_genl_family);
#endif #endif
out_unregister_pernet: out_unregister_pernet:
@ -564,8 +566,9 @@ void seg6_exit(void)
seg6_hmac_exit(); seg6_hmac_exit();
#endif #endif
#ifdef CONFIG_IPV6_SEG6_LWTUNNEL #ifdef CONFIG_IPV6_SEG6_LWTUNNEL
seg6_local_exit();
seg6_iptunnel_exit(); seg6_iptunnel_exit();
#endif #endif
unregister_pernet_subsys(&ip6_segments_ops);
genl_unregister_family(&seg6_genl_family); genl_unregister_family(&seg6_genl_family);
unregister_pernet_subsys(&ip6_segments_ops);
} }

View File

@ -965,6 +965,7 @@ int netlbl_enabled(void)
* @sk: the socket to label * @sk: the socket to label
* @family: protocol family * @family: protocol family
* @secattr: the security attributes * @secattr: the security attributes
* @sk_locked: true if caller holds the socket lock
* *
* Description: * Description:
* Attach the correct label to the given socket using the security attributes * Attach the correct label to the given socket using the security attributes
@ -977,7 +978,8 @@ int netlbl_enabled(void)
*/ */
int netlbl_sock_setattr(struct sock *sk, int netlbl_sock_setattr(struct sock *sk,
u16 family, u16 family,
const struct netlbl_lsm_secattr *secattr) const struct netlbl_lsm_secattr *secattr,
bool sk_locked)
{ {
int ret_val; int ret_val;
struct netlbl_dom_map *dom_entry; struct netlbl_dom_map *dom_entry;
@ -997,7 +999,7 @@ int netlbl_sock_setattr(struct sock *sk,
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_sock_setattr(sk, ret_val = cipso_v4_sock_setattr(sk,
dom_entry->def.cipso, dom_entry->def.cipso,
secattr); secattr, sk_locked);
break; break;
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
ret_val = 0; ret_val = 0;
@ -1090,6 +1092,28 @@ int netlbl_sock_getattr(struct sock *sk,
return ret_val; return ret_val;
} }
/**
* netlbl_sk_lock_check - Check if the socket lock has been acquired.
* @sk: the socket to be checked
*
* Return: true if socket @sk is locked or if lock debugging is disabled at
* runtime or compile-time; false otherwise
*
*/
#ifdef CONFIG_LOCKDEP
bool netlbl_sk_lock_check(struct sock *sk)
{
if (debug_locks)
return lockdep_sock_is_held(sk);
return true;
}
#else
bool netlbl_sk_lock_check(struct sock *sk)
{
return true;
}
#endif
/** /**
* netlbl_conn_setattr - Label a connected socket using the correct protocol * netlbl_conn_setattr - Label a connected socket using the correct protocol
* @sk: the socket to label * @sk: the socket to label
@ -1126,7 +1150,8 @@ int netlbl_conn_setattr(struct sock *sk,
switch (entry->type) { switch (entry->type) {
case NETLBL_NLTYPE_CIPSOV4: case NETLBL_NLTYPE_CIPSOV4:
ret_val = cipso_v4_sock_setattr(sk, ret_val = cipso_v4_sock_setattr(sk,
entry->cipso, secattr); entry->cipso, secattr,
netlbl_sk_lock_check(sk));
break; break;
case NETLBL_NLTYPE_UNLABELED: case NETLBL_NLTYPE_UNLABELED:
/* just delete the protocols we support for right now /* just delete the protocols we support for right now

View File

@ -561,7 +561,6 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
*/ */
key->tp.src = htons(icmp->icmp6_type); key->tp.src = htons(icmp->icmp6_type);
key->tp.dst = htons(icmp->icmp6_code); key->tp.dst = htons(icmp->icmp6_code);
memset(&key->ipv6.nd, 0, sizeof(key->ipv6.nd));
if (icmp->icmp6_code == 0 && if (icmp->icmp6_code == 0 &&
(icmp->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION || (icmp->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION ||
@ -570,6 +569,8 @@ static int parse_icmpv6(struct sk_buff *skb, struct sw_flow_key *key,
struct nd_msg *nd; struct nd_msg *nd;
int offset; int offset;
memset(&key->ipv6.nd, 0, sizeof(key->ipv6.nd));
/* In order to process neighbor discovery options, we need the /* In order to process neighbor discovery options, we need the
* entire packet. * entire packet.
*/ */

View File

@ -2224,7 +2224,7 @@ static int unix_stream_sendmsg(struct socket *sock, struct msghdr *msg,
goto out_err; goto out_err;
} }
if (sk->sk_shutdown & SEND_SHUTDOWN) if (READ_ONCE(sk->sk_shutdown) & SEND_SHUTDOWN)
goto pipe_err; goto pipe_err;
while (sent < len) { while (sent < len) {

View File

@ -402,7 +402,10 @@ int selinux_netlbl_socket_post_create(struct sock *sk, u16 family)
secattr = selinux_netlbl_sock_genattr(sk); secattr = selinux_netlbl_sock_genattr(sk);
if (secattr == NULL) if (secattr == NULL)
return -ENOMEM; return -ENOMEM;
rc = netlbl_sock_setattr(sk, family, secattr); /* On socket creation, replacement of IP options is safe even if
* the caller does not hold the socket lock.
*/
rc = netlbl_sock_setattr(sk, family, secattr, true);
switch (rc) { switch (rc) {
case 0: case 0:
sksec->nlbl_state = NLBL_LABELED; sksec->nlbl_state = NLBL_LABELED;

View File

@ -2565,7 +2565,8 @@ static int smack_netlbl_add(struct sock *sk)
local_bh_disable(); local_bh_disable();
bh_lock_sock_nested(sk); bh_lock_sock_nested(sk);
rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel); rc = netlbl_sock_setattr(sk, sk->sk_family, &skp->smk_netlabel,
netlbl_sk_lock_check(sk));
switch (rc) { switch (rc) {
case 0: case 0:
ssp->smk_state = SMK_NETLBL_LABELED; ssp->smk_state = SMK_NETLBL_LABELED;

View File

@ -24,6 +24,7 @@ enum sockopt_test_error {
static struct sockopt_test { static struct sockopt_test {
const char *descr; const char *descr;
const struct bpf_insn insns[64]; const struct bpf_insn insns[64];
enum bpf_prog_type prog_type;
enum bpf_attach_type attach_type; enum bpf_attach_type attach_type;
enum bpf_attach_type expected_attach_type; enum bpf_attach_type expected_attach_type;
@ -928,9 +929,40 @@ static struct sockopt_test {
.error = EPERM_SETSOCKOPT, .error = EPERM_SETSOCKOPT,
}, },
/* ==================== prog_type ==================== */
{
.descr = "can attach only BPF_CGROUP_SETSOCKOP",
.insns = {
/* return 1 */
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
.attach_type = BPF_CGROUP_SETSOCKOPT,
.expected_attach_type = 0,
.error = DENY_ATTACH,
},
{
.descr = "can attach only BPF_CGROUP_GETSOCKOP",
.insns = {
/* return 1 */
BPF_MOV64_IMM(BPF_REG_0, 1),
BPF_EXIT_INSN(),
},
.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
.attach_type = BPF_CGROUP_GETSOCKOPT,
.expected_attach_type = 0,
.error = DENY_ATTACH,
},
}; };
static int load_prog(const struct bpf_insn *insns, static int load_prog(const struct bpf_insn *insns,
enum bpf_prog_type prog_type,
enum bpf_attach_type expected_attach_type) enum bpf_attach_type expected_attach_type)
{ {
LIBBPF_OPTS(bpf_prog_load_opts, opts, LIBBPF_OPTS(bpf_prog_load_opts, opts,
@ -947,7 +979,7 @@ static int load_prog(const struct bpf_insn *insns,
} }
insns_cnt++; insns_cnt++;
fd = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SOCKOPT, NULL, "GPL", insns, insns_cnt, &opts); fd = bpf_prog_load(prog_type, NULL, "GPL", insns, insns_cnt, &opts);
if (verbose && fd < 0) if (verbose && fd < 0)
fprintf(stderr, "%s\n", bpf_log_buf); fprintf(stderr, "%s\n", bpf_log_buf);
@ -1036,13 +1068,18 @@ static int call_getsockopt(bool use_io_uring, int fd, int level, int optname,
return getsockopt(fd, level, optname, optval, optlen); return getsockopt(fd, level, optname, optval, optlen);
} }
static int run_test(int cgroup_fd, struct sockopt_test *test, bool use_io_uring) static int run_test(int cgroup_fd, struct sockopt_test *test, bool use_io_uring,
bool use_link)
{ {
int sock_fd, err, prog_fd; int prog_type = BPF_PROG_TYPE_CGROUP_SOCKOPT;
int sock_fd, err, prog_fd, link_fd = -1;
void *optval = NULL; void *optval = NULL;
int ret = 0; int ret = 0;
prog_fd = load_prog(test->insns, test->expected_attach_type); if (test->prog_type)
prog_type = test->prog_type;
prog_fd = load_prog(test->insns, prog_type, test->expected_attach_type);
if (prog_fd < 0) { if (prog_fd < 0) {
if (test->error == DENY_LOAD) if (test->error == DENY_LOAD)
return 0; return 0;
@ -1051,7 +1088,12 @@ static int run_test(int cgroup_fd, struct sockopt_test *test, bool use_io_uring)
return -1; return -1;
} }
err = bpf_prog_attach(prog_fd, cgroup_fd, test->attach_type, 0); if (use_link) {
err = bpf_link_create(prog_fd, cgroup_fd, test->attach_type, NULL);
link_fd = err;
} else {
err = bpf_prog_attach(prog_fd, cgroup_fd, test->attach_type, 0);
}
if (err < 0) { if (err < 0) {
if (test->error == DENY_ATTACH) if (test->error == DENY_ATTACH)
goto close_prog_fd; goto close_prog_fd;
@ -1142,7 +1184,12 @@ free_optval:
close_sock_fd: close_sock_fd:
close(sock_fd); close(sock_fd);
detach_prog: detach_prog:
bpf_prog_detach2(prog_fd, cgroup_fd, test->attach_type); if (use_link) {
if (link_fd >= 0)
close(link_fd);
} else {
bpf_prog_detach2(prog_fd, cgroup_fd, test->attach_type);
}
close_prog_fd: close_prog_fd:
close(prog_fd); close(prog_fd);
return ret; return ret;
@ -1160,10 +1207,12 @@ void test_sockopt(void)
if (!test__start_subtest(tests[i].descr)) if (!test__start_subtest(tests[i].descr))
continue; continue;
ASSERT_OK(run_test(cgroup_fd, &tests[i], false), ASSERT_OK(run_test(cgroup_fd, &tests[i], false, false),
tests[i].descr);
ASSERT_OK(run_test(cgroup_fd, &tests[i], false, true),
tests[i].descr); tests[i].descr);
if (tests[i].io_uring_support) if (tests[i].io_uring_support)
ASSERT_OK(run_test(cgroup_fd, &tests[i], true), ASSERT_OK(run_test(cgroup_fd, &tests[i], true, false),
tests[i].descr); tests[i].descr);
} }

View File

@ -210,8 +210,8 @@ check_features()
test_ipv4_forward() test_ipv4_forward()
{ {
RESULT4=$(ip netns exec "${LISTENER}" nc -w 1 -l -u 239.0.0.1 4000) RESULT4=$(ip netns exec "${LISTENER}" timeout 15 socat - UDP4-LISTEN:4000,readbytes=128 || true)
if [ "$RESULT4" == "172.17.0.2" ]; then if echo "$RESULT4" | grep -q "172.17.0.2"; then
printf "TEST: %-60s [ OK ]\n" "IPv4 amt multicast forwarding" printf "TEST: %-60s [ OK ]\n" "IPv4 amt multicast forwarding"
exit 0 exit 0
else else
@ -222,8 +222,8 @@ test_ipv4_forward()
test_ipv6_forward() test_ipv6_forward()
{ {
RESULT6=$(ip netns exec "${LISTENER}" nc -w 1 -l -u ff0e::5:6 6000) RESULT6=$(ip netns exec "${LISTENER}" timeout 15 socat - UDP6-LISTEN:6000,readbytes=128 || true)
if [ "$RESULT6" == "2001:db8:3::2" ]; then if echo "$RESULT6" | grep -q "2001:db8:3::2"; then
printf "TEST: %-60s [ OK ]\n" "IPv6 amt multicast forwarding" printf "TEST: %-60s [ OK ]\n" "IPv6 amt multicast forwarding"
exit 0 exit 0
else else
@ -236,14 +236,14 @@ send_mcast4()
{ {
sleep 2 sleep 2
ip netns exec "${SOURCE}" bash -c \ ip netns exec "${SOURCE}" bash -c \
'echo 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' & 'printf "%s %128s" 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' &
} }
send_mcast6() send_mcast6()
{ {
sleep 2 sleep 2
ip netns exec "${SOURCE}" bash -c \ ip netns exec "${SOURCE}" bash -c \
'echo 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' & 'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' &
} }
check_features check_features

View File

@ -30,6 +30,7 @@ CONFIG_IP_GRE=m
CONFIG_NETFILTER=y CONFIG_NETFILTER=y
CONFIG_NETFILTER_ADVANCED=y CONFIG_NETFILTER_ADVANCED=y
CONFIG_NF_CONNTRACK=m CONFIG_NF_CONNTRACK=m
CONFIG_IPV6_MROUTE=y
CONFIG_IPV6_SIT=y CONFIG_IPV6_SIT=y
CONFIG_IP_DCCP=m CONFIG_IP_DCCP=m
CONFIG_NF_NAT=m CONFIG_NF_NAT=m