mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-09-18 22:14:16 +00:00
Including fixes from Bluetooth.
Current release - new code bugs: - eth: txgbe: fix the issue of TX failure - eth: ngbe: specify IRQ vector when the number of VFs is 7 Previous releases - regressions: - sched: always pass notifications when child class becomes empty - ipv4: fix stat increase when udp early demux drops the packet - bluetooth: prevent unintended pause by checking if advertising is active - virtio: fix error reporting in virtqueue_resize - eth: virtio-net: - ensure the received length does not exceed allocated size - fix the xsk frame's length check - eth: lan78xx: fix WARN in __netif_napi_del_locked on disconnect Previous releases - always broken: - bluetooth: mesh: check instances prior disabling advertising - eth: idpf: convert control queue mutex to a spinlock - eth: dpaa2: fix xdp_rxq_info leak - eth: amd-xgbe: align CL37 AN sequence as per databook Signed-off-by: Paolo Abeni <pabeni@redhat.com> -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmhmfzQSHHBhYmVuaUBy ZWRoYXQuY29tAAoJECkkeY3MjxOk/GMP/ixlapKjTP/ggGIFO0nEDTm1tAFnhQl3 bBuwBDoGPjalb46WBO24SFSFYqvZwV6ZIYxCxCeBfmkPyEun0FBX6xjqUIZqohTZ u5ZSmKFkODMoxQWAG0hXBGvfeKg/GBMWJT761o5IB2XvknRlqHq6uufUBcalvlJK t58ykSYp2wjfowXSRQ4jEZnr4HZzVuvarhbCB9hJWv206fdk4LiC07teHB1VhW4w LYmBQChp8SXDFCCYZajum0cNCzx78q90lGzz+MEErVXdXXnRVeqRAUY+k4Vd/Fz+ 0OY1vZJ7xgFpy2ns3Z6TH8D41P9whBI8jUYXZ5nA45J8N5wdEQo8oVHlRe9a6Y/E 0oC+DPahhSQAq8BKGFtYSyyURGJvd4+TpQP/LV4e83myReW8i0ZKtyXVgH0Cibwb 529l6wIXBAcLK03tyYwmoCI2VjJbRoMV3nMCeiACCtDExK1YCa3dhjQ82fa8voLc MIn7zXAGf12IKca39ZapRrdaooaqvSG4htxTn94vEqScNu0wi1cymvG47h9bDrES cPyS4/MIUH0sduSDVL5PpFYfIDhqS3mpc0e8Nc3pOy7VLQ9kvtBX37OaO/tX5aeh SWU+8q8y1Cnq0+mcUUHpENFMOgZEC5UO6rdeaJB3Nu0vlHlDEZoEkUXSkHEfsf2F aodwE/oPyQCg =O7OS -----END PGP SIGNATURE----- Merge tag 'net-6.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Including fixes from Bluetooth. Current release - new code bugs: - eth: - txgbe: fix the issue of TX failure - ngbe: specify IRQ vector when the number of VFs is 7 Previous releases - regressions: - sched: always pass notifications when child class becomes empty - ipv4: fix stat increase when udp early demux drops the packet - bluetooth: prevent unintended pause by checking if advertising is active - virtio: fix error reporting in virtqueue_resize - eth: - virtio-net: - ensure the received length does not exceed allocated size - fix the xsk frame's length check - lan78xx: fix WARN in __netif_napi_del_locked on disconnect Previous releases - always broken: - bluetooth: mesh: check instances prior disabling advertising - eth: - idpf: convert control queue mutex to a spinlock - dpaa2: fix xdp_rxq_info leak - amd-xgbe: align CL37 AN sequence as per databook" * tag 'net-6.16-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (38 commits) vsock/vmci: Clear the vmci transport packet properly when initializing it dt-bindings: net: sophgo,sg2044-dwmac: Drop status from the example net: ngbe: specify IRQ vector when the number of VFs is 7 net: wangxun: revert the adjustment of the IRQ vector sequence net: txgbe: request MISC IRQ in ndo_open virtio_net: Enforce minimum TX ring size for reliability virtio_net: Cleanup '2+MAX_SKB_FRAGS' virtio_ring: Fix error reporting in virtqueue_resize virtio-net: xsk: rx: fix the frame's length check virtio-net: use the check_mergeable_len helper virtio-net: remove redundant truesize check with PAGE_SIZE virtio-net: ensure the received length does not exceed allocated size net: ipv4: fix stat increase when udp early demux drops the packet net: libwx: fix the incorrect display of the queue number amd-xgbe: do not double read link status net/sched: Always pass notifications when child class becomes empty nui: Fix dma_mapping_error() check rose: fix dangling neighbour pointers in rose_rt_device_down() enic: fix incorrect MTU comparison in enic_change_mtu() amd-xgbe: align CL37 AN sequence as per databook ...
This commit is contained in:
commit
17bbde2e17
38 changed files with 494 additions and 296 deletions
|
@ -80,6 +80,8 @@ examples:
|
|||
interrupt-parent = <&intc>;
|
||||
interrupts = <296 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupt-names = "macirq";
|
||||
phy-handle = <&phy0>;
|
||||
phy-mode = "rgmii-id";
|
||||
resets = <&rst 30>;
|
||||
reset-names = "stmmaceth";
|
||||
snps,multicast-filter-bins = <0>;
|
||||
|
@ -91,7 +93,6 @@ examples:
|
|||
snps,mtl-rx-config = <&gmac0_mtl_rx_setup>;
|
||||
snps,mtl-tx-config = <&gmac0_mtl_tx_setup>;
|
||||
snps,axi-config = <&gmac0_stmmac_axi_setup>;
|
||||
status = "disabled";
|
||||
|
||||
gmac0_mtl_rx_setup: rx-queues-config {
|
||||
snps,rx-queues-to-use = <8>;
|
||||
|
|
|
@ -16,11 +16,13 @@ User interface
|
|||
Creating a TLS connection
|
||||
-------------------------
|
||||
|
||||
First create a new TCP socket and set the TLS ULP.
|
||||
First create a new TCP socket and once the connection is established set the
|
||||
TLS ULP.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
connect(sock, addr, addrlen);
|
||||
setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls"));
|
||||
|
||||
Setting the TLS ULP allows us to set/get TLS socket options. Currently
|
||||
|
|
|
@ -312,7 +312,7 @@ Posting as one thread is discouraged because it confuses patchwork
|
|||
(as of patchwork 2.2.2).
|
||||
|
||||
Co-posting selftests
|
||||
--------------------
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Selftests should be part of the same series as the code changes.
|
||||
Specifically for fixes both code change and related test should go into
|
||||
|
|
10
MAINTAINERS
10
MAINTAINERS
|
@ -15550,6 +15550,7 @@ F: drivers/net/ethernet/mellanox/mlx4/en_*
|
|||
MELLANOX ETHERNET DRIVER (mlx5e)
|
||||
M: Saeed Mahameed <saeedm@nvidia.com>
|
||||
M: Tariq Toukan <tariqt@nvidia.com>
|
||||
M: Mark Bloch <mbloch@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://www.nvidia.com/networking/
|
||||
|
@ -15619,6 +15620,7 @@ MELLANOX MLX5 core VPI driver
|
|||
M: Saeed Mahameed <saeedm@nvidia.com>
|
||||
M: Leon Romanovsky <leonro@nvidia.com>
|
||||
M: Tariq Toukan <tariqt@nvidia.com>
|
||||
M: Mark Bloch <mbloch@nvidia.com>
|
||||
L: netdev@vger.kernel.org
|
||||
L: linux-rdma@vger.kernel.org
|
||||
S: Maintained
|
||||
|
@ -21198,7 +21200,7 @@ M: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
|
|||
L: netdev@vger.kernel.org
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/renesas,r9a09g057-gbeth.yaml
|
||||
F: Documentation/devicetree/bindings/net/renesas,rzv2h-gbeth.yaml
|
||||
F: drivers/net/ethernet/stmicro/stmmac/dwmac-renesas-gbeth.c
|
||||
|
||||
RENESAS RZ/V2H(P) USB2PHY PORT RESET DRIVER
|
||||
|
@ -22586,9 +22588,11 @@ S: Maintained
|
|||
F: drivers/misc/sgi-xp/
|
||||
|
||||
SHARED MEMORY COMMUNICATIONS (SMC) SOCKETS
|
||||
M: D. Wythe <alibuda@linux.alibaba.com>
|
||||
M: Dust Li <dust.li@linux.alibaba.com>
|
||||
M: Sidraya Jayagond <sidraya@linux.ibm.com>
|
||||
M: Wenjia Zhang <wenjia@linux.ibm.com>
|
||||
M: Jan Karcher <jaka@linux.ibm.com>
|
||||
R: D. Wythe <alibuda@linux.alibaba.com>
|
||||
R: Mahanta Jambigi <mjambigi@linux.ibm.com>
|
||||
R: Tony Lu <tonylu@linux.alibaba.com>
|
||||
R: Wen Gu <guwen@linux.alibaba.com>
|
||||
L: linux-rdma@vger.kernel.org
|
||||
|
|
|
@ -1269,6 +1269,8 @@
|
|||
#define MDIO_VEND2_CTRL1_SS13 BIT(13)
|
||||
#endif
|
||||
|
||||
#define XGBE_VEND2_MAC_AUTO_SW BIT(9)
|
||||
|
||||
/* MDIO mask values */
|
||||
#define XGBE_AN_CL73_INT_CMPLT BIT(0)
|
||||
#define XGBE_AN_CL73_INC_LINK BIT(1)
|
||||
|
|
|
@ -266,6 +266,10 @@ static void xgbe_an37_set(struct xgbe_prv_data *pdata, bool enable,
|
|||
reg |= MDIO_VEND2_CTRL1_AN_RESTART;
|
||||
|
||||
XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_CTRL1, reg);
|
||||
|
||||
reg = XMDIO_READ(pdata, MDIO_MMD_VEND2, MDIO_PCS_DIG_CTRL);
|
||||
reg |= XGBE_VEND2_MAC_AUTO_SW;
|
||||
XMDIO_WRITE(pdata, MDIO_MMD_VEND2, MDIO_PCS_DIG_CTRL, reg);
|
||||
}
|
||||
|
||||
static void xgbe_an37_restart(struct xgbe_prv_data *pdata)
|
||||
|
@ -894,6 +898,11 @@ static void xgbe_an37_init(struct xgbe_prv_data *pdata)
|
|||
|
||||
netif_dbg(pdata, link, pdata->netdev, "CL37 AN (%s) initialized\n",
|
||||
(pdata->an_mode == XGBE_AN_MODE_CL37) ? "BaseX" : "SGMII");
|
||||
|
||||
reg = XMDIO_READ(pdata, MDIO_MMD_AN, MDIO_CTRL1);
|
||||
reg &= ~MDIO_AN_CTRL1_ENABLE;
|
||||
XMDIO_WRITE(pdata, MDIO_MMD_AN, MDIO_CTRL1, reg);
|
||||
|
||||
}
|
||||
|
||||
static void xgbe_an73_init(struct xgbe_prv_data *pdata)
|
||||
|
@ -1295,6 +1304,10 @@ static void xgbe_phy_status(struct xgbe_prv_data *pdata)
|
|||
|
||||
pdata->phy.link = pdata->phy_if.phy_impl.link_status(pdata,
|
||||
&an_restart);
|
||||
/* bail out if the link status register read fails */
|
||||
if (pdata->phy.link < 0)
|
||||
return;
|
||||
|
||||
if (an_restart) {
|
||||
xgbe_phy_config_aneg(pdata);
|
||||
goto adjust_link;
|
||||
|
|
|
@ -2746,8 +2746,7 @@ static bool xgbe_phy_valid_speed(struct xgbe_prv_data *pdata, int speed)
|
|||
static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
|
||||
{
|
||||
struct xgbe_phy_data *phy_data = pdata->phy_data;
|
||||
unsigned int reg;
|
||||
int ret;
|
||||
int reg, ret;
|
||||
|
||||
*an_restart = 0;
|
||||
|
||||
|
@ -2781,11 +2780,20 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Link status is latched low, so read once to clear
|
||||
* and then read again to get current state
|
||||
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
|
||||
/* Link status is latched low so that momentary link drops
|
||||
* can be detected. If link was already down read again
|
||||
* to get the latest state.
|
||||
*/
|
||||
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
|
||||
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
|
||||
|
||||
if (!pdata->phy.link && !(reg & MDIO_STAT1_LSTATUS)) {
|
||||
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
|
||||
if (reg < 0)
|
||||
return reg;
|
||||
}
|
||||
|
||||
if (pdata->en_rx_adap) {
|
||||
/* if the link is available and adaptation is done,
|
||||
|
@ -2804,9 +2812,7 @@ static int xgbe_phy_link_status(struct xgbe_prv_data *pdata, int *an_restart)
|
|||
xgbe_phy_set_mode(pdata, phy_data->cur_mode);
|
||||
}
|
||||
|
||||
/* check again for the link and adaptation status */
|
||||
reg = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_STAT1);
|
||||
if ((reg & MDIO_STAT1_LSTATUS) && pdata->rx_adapt_done)
|
||||
if (pdata->rx_adapt_done)
|
||||
return 1;
|
||||
} else if (reg & MDIO_STAT1_LSTATUS)
|
||||
return 1;
|
||||
|
|
|
@ -183,12 +183,12 @@
|
|||
#define XGBE_LINK_TIMEOUT 5
|
||||
#define XGBE_KR_TRAINING_WAIT_ITER 50
|
||||
|
||||
#define XGBE_SGMII_AN_LINK_STATUS BIT(1)
|
||||
#define XGBE_SGMII_AN_LINK_DUPLEX BIT(1)
|
||||
#define XGBE_SGMII_AN_LINK_SPEED (BIT(2) | BIT(3))
|
||||
#define XGBE_SGMII_AN_LINK_SPEED_10 0x00
|
||||
#define XGBE_SGMII_AN_LINK_SPEED_100 0x04
|
||||
#define XGBE_SGMII_AN_LINK_SPEED_1000 0x08
|
||||
#define XGBE_SGMII_AN_LINK_DUPLEX BIT(4)
|
||||
#define XGBE_SGMII_AN_LINK_STATUS BIT(4)
|
||||
|
||||
/* ECC correctable error notification window (seconds) */
|
||||
#define XGBE_ECC_LIMIT 60
|
||||
|
|
|
@ -1861,14 +1861,21 @@ static u16 atl1_alloc_rx_buffers(struct atl1_adapter *adapter)
|
|||
break;
|
||||
}
|
||||
|
||||
buffer_info->alloced = 1;
|
||||
buffer_info->skb = skb;
|
||||
buffer_info->length = (u16) adapter->rx_buffer_len;
|
||||
page = virt_to_page(skb->data);
|
||||
offset = offset_in_page(skb->data);
|
||||
buffer_info->dma = dma_map_page(&pdev->dev, page, offset,
|
||||
adapter->rx_buffer_len,
|
||||
DMA_FROM_DEVICE);
|
||||
if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
|
||||
kfree_skb(skb);
|
||||
adapter->soft_stats.rx_dropped++;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer_info->alloced = 1;
|
||||
buffer_info->skb = skb;
|
||||
buffer_info->length = (u16)adapter->rx_buffer_len;
|
||||
|
||||
rfd_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
|
||||
rfd_desc->buf_len = cpu_to_le16(adapter->rx_buffer_len);
|
||||
rfd_desc->coalese = 0;
|
||||
|
@ -2183,8 +2190,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
||||
struct tx_packet_desc *ptpd)
|
||||
static bool atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
||||
struct tx_packet_desc *ptpd)
|
||||
{
|
||||
struct atl1_tpd_ring *tpd_ring = &adapter->tpd_ring;
|
||||
struct atl1_buffer *buffer_info;
|
||||
|
@ -2194,6 +2201,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
unsigned int nr_frags;
|
||||
unsigned int f;
|
||||
int retval;
|
||||
u16 first_mapped;
|
||||
u16 next_to_use;
|
||||
u16 data_len;
|
||||
u8 hdr_len;
|
||||
|
@ -2201,6 +2209,7 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
buf_len -= skb->data_len;
|
||||
nr_frags = skb_shinfo(skb)->nr_frags;
|
||||
next_to_use = atomic_read(&tpd_ring->next_to_use);
|
||||
first_mapped = next_to_use;
|
||||
buffer_info = &tpd_ring->buffer_info[next_to_use];
|
||||
BUG_ON(buffer_info->skb);
|
||||
/* put skb in last TPD */
|
||||
|
@ -2216,6 +2225,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
buffer_info->dma = dma_map_page(&adapter->pdev->dev, page,
|
||||
offset, hdr_len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma))
|
||||
goto dma_err;
|
||||
|
||||
if (++next_to_use == tpd_ring->count)
|
||||
next_to_use = 0;
|
||||
|
@ -2242,6 +2253,9 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
page, offset,
|
||||
buffer_info->length,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(&adapter->pdev->dev,
|
||||
buffer_info->dma))
|
||||
goto dma_err;
|
||||
if (++next_to_use == tpd_ring->count)
|
||||
next_to_use = 0;
|
||||
}
|
||||
|
@ -2254,6 +2268,8 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
buffer_info->dma = dma_map_page(&adapter->pdev->dev, page,
|
||||
offset, buf_len,
|
||||
DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(&adapter->pdev->dev, buffer_info->dma))
|
||||
goto dma_err;
|
||||
if (++next_to_use == tpd_ring->count)
|
||||
next_to_use = 0;
|
||||
}
|
||||
|
@ -2277,6 +2293,9 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
buffer_info->dma = skb_frag_dma_map(&adapter->pdev->dev,
|
||||
frag, i * ATL1_MAX_TX_BUF_LEN,
|
||||
buffer_info->length, DMA_TO_DEVICE);
|
||||
if (dma_mapping_error(&adapter->pdev->dev,
|
||||
buffer_info->dma))
|
||||
goto dma_err;
|
||||
|
||||
if (++next_to_use == tpd_ring->count)
|
||||
next_to_use = 0;
|
||||
|
@ -2285,6 +2304,22 @@ static void atl1_tx_map(struct atl1_adapter *adapter, struct sk_buff *skb,
|
|||
|
||||
/* last tpd's buffer-info */
|
||||
buffer_info->skb = skb;
|
||||
|
||||
return true;
|
||||
|
||||
dma_err:
|
||||
while (first_mapped != next_to_use) {
|
||||
buffer_info = &tpd_ring->buffer_info[first_mapped];
|
||||
dma_unmap_page(&adapter->pdev->dev,
|
||||
buffer_info->dma,
|
||||
buffer_info->length,
|
||||
DMA_TO_DEVICE);
|
||||
buffer_info->dma = 0;
|
||||
|
||||
if (++first_mapped == tpd_ring->count)
|
||||
first_mapped = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void atl1_tx_queue(struct atl1_adapter *adapter, u16 count,
|
||||
|
@ -2355,10 +2390,8 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
|
|||
|
||||
len = skb_headlen(skb);
|
||||
|
||||
if (unlikely(skb->len <= 0)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
if (unlikely(skb->len <= 0))
|
||||
goto drop_packet;
|
||||
|
||||
nr_frags = skb_shinfo(skb)->nr_frags;
|
||||
for (f = 0; f < nr_frags; f++) {
|
||||
|
@ -2371,10 +2404,9 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
|
|||
if (mss) {
|
||||
if (skb->protocol == htons(ETH_P_IP)) {
|
||||
proto_hdr_len = skb_tcp_all_headers(skb);
|
||||
if (unlikely(proto_hdr_len > len)) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
if (unlikely(proto_hdr_len > len))
|
||||
goto drop_packet;
|
||||
|
||||
/* need additional TPD ? */
|
||||
if (proto_hdr_len != len)
|
||||
count += (len - proto_hdr_len +
|
||||
|
@ -2406,23 +2438,26 @@ static netdev_tx_t atl1_xmit_frame(struct sk_buff *skb,
|
|||
}
|
||||
|
||||
tso = atl1_tso(adapter, skb, ptpd);
|
||||
if (tso < 0) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
if (tso < 0)
|
||||
goto drop_packet;
|
||||
|
||||
if (!tso) {
|
||||
ret_val = atl1_tx_csum(adapter, skb, ptpd);
|
||||
if (ret_val < 0) {
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
if (ret_val < 0)
|
||||
goto drop_packet;
|
||||
}
|
||||
|
||||
atl1_tx_map(adapter, skb, ptpd);
|
||||
if (!atl1_tx_map(adapter, skb, ptpd))
|
||||
goto drop_packet;
|
||||
|
||||
atl1_tx_queue(adapter, count, ptpd);
|
||||
atl1_update_mailbox(adapter);
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
drop_packet:
|
||||
adapter->soft_stats.tx_errors++;
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
}
|
||||
|
||||
static int atl1_rings_clean(struct napi_struct *napi, int budget)
|
||||
|
|
|
@ -1864,10 +1864,10 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu)
|
|||
if (enic_is_dynamic(enic) || enic_is_sriov_vf(enic))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (netdev->mtu > enic->port_mtu)
|
||||
if (new_mtu > enic->port_mtu)
|
||||
netdev_warn(netdev,
|
||||
"interface MTU (%d) set higher than port MTU (%d)\n",
|
||||
netdev->mtu, enic->port_mtu);
|
||||
new_mtu, enic->port_mtu);
|
||||
|
||||
return _enic_change_mtu(netdev, new_mtu);
|
||||
}
|
||||
|
|
|
@ -3939,6 +3939,7 @@ static int dpaa2_eth_setup_rx_flow(struct dpaa2_eth_priv *priv,
|
|||
MEM_TYPE_PAGE_ORDER0, NULL);
|
||||
if (err) {
|
||||
dev_err(dev, "xdp_rxq_info_reg_mem_model failed\n");
|
||||
xdp_rxq_info_unreg(&fq->channel->xdp_rxq);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -4432,17 +4433,25 @@ static int dpaa2_eth_bind_dpni(struct dpaa2_eth_priv *priv)
|
|||
return -EINVAL;
|
||||
}
|
||||
if (err)
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = dpni_get_qdid(priv->mc_io, 0, priv->mc_token,
|
||||
DPNI_QUEUE_TX, &priv->tx_qdid);
|
||||
if (err) {
|
||||
dev_err(dev, "dpni_get_qdid() failed\n");
|
||||
return err;
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
out:
|
||||
while (i--) {
|
||||
if (priv->fq[i].type == DPAA2_RX_FQ &&
|
||||
xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq))
|
||||
xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq);
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Allocate rings for storing incoming frame descriptors */
|
||||
|
@ -4825,6 +4834,17 @@ static void dpaa2_eth_del_ch_napi(struct dpaa2_eth_priv *priv)
|
|||
}
|
||||
}
|
||||
|
||||
static void dpaa2_eth_free_rx_xdp_rxq(struct dpaa2_eth_priv *priv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < priv->num_fqs; i++) {
|
||||
if (priv->fq[i].type == DPAA2_RX_FQ &&
|
||||
xdp_rxq_info_is_reg(&priv->fq[i].channel->xdp_rxq))
|
||||
xdp_rxq_info_unreg(&priv->fq[i].channel->xdp_rxq);
|
||||
}
|
||||
}
|
||||
|
||||
static int dpaa2_eth_probe(struct fsl_mc_device *dpni_dev)
|
||||
{
|
||||
struct device *dev;
|
||||
|
@ -5028,6 +5048,7 @@ err_alloc_percpu_extras:
|
|||
free_percpu(priv->percpu_stats);
|
||||
err_alloc_percpu_stats:
|
||||
dpaa2_eth_del_ch_napi(priv);
|
||||
dpaa2_eth_free_rx_xdp_rxq(priv);
|
||||
err_bind:
|
||||
dpaa2_eth_free_dpbps(priv);
|
||||
err_dpbp_setup:
|
||||
|
@ -5080,6 +5101,7 @@ static void dpaa2_eth_remove(struct fsl_mc_device *ls_dev)
|
|||
free_percpu(priv->percpu_extras);
|
||||
|
||||
dpaa2_eth_del_ch_napi(priv);
|
||||
dpaa2_eth_free_rx_xdp_rxq(priv);
|
||||
dpaa2_eth_free_dpbps(priv);
|
||||
dpaa2_eth_free_dpio(priv);
|
||||
dpaa2_eth_free_dpni(priv);
|
||||
|
|
|
@ -96,7 +96,7 @@ static void idpf_ctlq_init_rxq_bufs(struct idpf_ctlq_info *cq)
|
|||
*/
|
||||
static void idpf_ctlq_shutdown(struct idpf_hw *hw, struct idpf_ctlq_info *cq)
|
||||
{
|
||||
mutex_lock(&cq->cq_lock);
|
||||
spin_lock(&cq->cq_lock);
|
||||
|
||||
/* free ring buffers and the ring itself */
|
||||
idpf_ctlq_dealloc_ring_res(hw, cq);
|
||||
|
@ -104,8 +104,7 @@ static void idpf_ctlq_shutdown(struct idpf_hw *hw, struct idpf_ctlq_info *cq)
|
|||
/* Set ring_size to 0 to indicate uninitialized queue */
|
||||
cq->ring_size = 0;
|
||||
|
||||
mutex_unlock(&cq->cq_lock);
|
||||
mutex_destroy(&cq->cq_lock);
|
||||
spin_unlock(&cq->cq_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -173,7 +172,7 @@ int idpf_ctlq_add(struct idpf_hw *hw,
|
|||
|
||||
idpf_ctlq_init_regs(hw, cq, is_rxq);
|
||||
|
||||
mutex_init(&cq->cq_lock);
|
||||
spin_lock_init(&cq->cq_lock);
|
||||
|
||||
list_add(&cq->cq_list, &hw->cq_list_head);
|
||||
|
||||
|
@ -272,7 +271,7 @@ int idpf_ctlq_send(struct idpf_hw *hw, struct idpf_ctlq_info *cq,
|
|||
int err = 0;
|
||||
int i;
|
||||
|
||||
mutex_lock(&cq->cq_lock);
|
||||
spin_lock(&cq->cq_lock);
|
||||
|
||||
/* Ensure there are enough descriptors to send all messages */
|
||||
num_desc_avail = IDPF_CTLQ_DESC_UNUSED(cq);
|
||||
|
@ -332,7 +331,7 @@ int idpf_ctlq_send(struct idpf_hw *hw, struct idpf_ctlq_info *cq,
|
|||
wr32(hw, cq->reg.tail, cq->next_to_use);
|
||||
|
||||
err_unlock:
|
||||
mutex_unlock(&cq->cq_lock);
|
||||
spin_unlock(&cq->cq_lock);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -364,7 +363,7 @@ int idpf_ctlq_clean_sq(struct idpf_ctlq_info *cq, u16 *clean_count,
|
|||
if (*clean_count > cq->ring_size)
|
||||
return -EBADR;
|
||||
|
||||
mutex_lock(&cq->cq_lock);
|
||||
spin_lock(&cq->cq_lock);
|
||||
|
||||
ntc = cq->next_to_clean;
|
||||
|
||||
|
@ -397,7 +396,7 @@ int idpf_ctlq_clean_sq(struct idpf_ctlq_info *cq, u16 *clean_count,
|
|||
|
||||
cq->next_to_clean = ntc;
|
||||
|
||||
mutex_unlock(&cq->cq_lock);
|
||||
spin_unlock(&cq->cq_lock);
|
||||
|
||||
/* Return number of descriptors actually cleaned */
|
||||
*clean_count = i;
|
||||
|
@ -435,7 +434,7 @@ int idpf_ctlq_post_rx_buffs(struct idpf_hw *hw, struct idpf_ctlq_info *cq,
|
|||
if (*buff_count > 0)
|
||||
buffs_avail = true;
|
||||
|
||||
mutex_lock(&cq->cq_lock);
|
||||
spin_lock(&cq->cq_lock);
|
||||
|
||||
if (tbp >= cq->ring_size)
|
||||
tbp = 0;
|
||||
|
@ -524,7 +523,7 @@ post_buffs_out:
|
|||
wr32(hw, cq->reg.tail, cq->next_to_post);
|
||||
}
|
||||
|
||||
mutex_unlock(&cq->cq_lock);
|
||||
spin_unlock(&cq->cq_lock);
|
||||
|
||||
/* return the number of buffers that were not posted */
|
||||
*buff_count = *buff_count - i;
|
||||
|
@ -552,7 +551,7 @@ int idpf_ctlq_recv(struct idpf_ctlq_info *cq, u16 *num_q_msg,
|
|||
u16 i;
|
||||
|
||||
/* take the lock before we start messing with the ring */
|
||||
mutex_lock(&cq->cq_lock);
|
||||
spin_lock(&cq->cq_lock);
|
||||
|
||||
ntc = cq->next_to_clean;
|
||||
|
||||
|
@ -614,7 +613,7 @@ int idpf_ctlq_recv(struct idpf_ctlq_info *cq, u16 *num_q_msg,
|
|||
|
||||
cq->next_to_clean = ntc;
|
||||
|
||||
mutex_unlock(&cq->cq_lock);
|
||||
spin_unlock(&cq->cq_lock);
|
||||
|
||||
*num_q_msg = i;
|
||||
if (*num_q_msg == 0)
|
||||
|
|
|
@ -99,7 +99,7 @@ struct idpf_ctlq_info {
|
|||
|
||||
enum idpf_ctlq_type cq_type;
|
||||
int q_id;
|
||||
struct mutex cq_lock; /* control queue lock */
|
||||
spinlock_t cq_lock; /* control queue lock */
|
||||
/* used for interrupt processing */
|
||||
u16 next_to_use;
|
||||
u16 next_to_clean;
|
||||
|
|
|
@ -47,7 +47,7 @@ static u32 idpf_get_rxfh_key_size(struct net_device *netdev)
|
|||
struct idpf_vport_user_config_data *user_config;
|
||||
|
||||
if (!idpf_is_cap_ena_all(np->adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS))
|
||||
return -EOPNOTSUPP;
|
||||
return 0;
|
||||
|
||||
user_config = &np->adapter->vport_config[np->vport_idx]->user_config;
|
||||
|
||||
|
@ -66,7 +66,7 @@ static u32 idpf_get_rxfh_indir_size(struct net_device *netdev)
|
|||
struct idpf_vport_user_config_data *user_config;
|
||||
|
||||
if (!idpf_is_cap_ena_all(np->adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS))
|
||||
return -EOPNOTSUPP;
|
||||
return 0;
|
||||
|
||||
user_config = &np->adapter->vport_config[np->vport_idx]->user_config;
|
||||
|
||||
|
|
|
@ -2314,8 +2314,12 @@ void *idpf_alloc_dma_mem(struct idpf_hw *hw, struct idpf_dma_mem *mem, u64 size)
|
|||
struct idpf_adapter *adapter = hw->back;
|
||||
size_t sz = ALIGN(size, 4096);
|
||||
|
||||
mem->va = dma_alloc_coherent(&adapter->pdev->dev, sz,
|
||||
&mem->pa, GFP_KERNEL);
|
||||
/* The control queue resources are freed under a spinlock, contiguous
|
||||
* pages will avoid IOMMU remapping and the use vmap (and vunmap in
|
||||
* dma_free_*() path.
|
||||
*/
|
||||
mem->va = dma_alloc_attrs(&adapter->pdev->dev, sz, &mem->pa,
|
||||
GFP_KERNEL, DMA_ATTR_FORCE_CONTIGUOUS);
|
||||
mem->size = sz;
|
||||
|
||||
return mem->va;
|
||||
|
@ -2330,8 +2334,8 @@ void idpf_free_dma_mem(struct idpf_hw *hw, struct idpf_dma_mem *mem)
|
|||
{
|
||||
struct idpf_adapter *adapter = hw->back;
|
||||
|
||||
dma_free_coherent(&adapter->pdev->dev, mem->size,
|
||||
mem->va, mem->pa);
|
||||
dma_free_attrs(&adapter->pdev->dev, mem->size,
|
||||
mem->va, mem->pa, DMA_ATTR_FORCE_CONTIGUOUS);
|
||||
mem->size = 0;
|
||||
mem->va = NULL;
|
||||
mem->pa = 0;
|
||||
|
|
|
@ -7115,6 +7115,10 @@ static int igc_probe(struct pci_dev *pdev,
|
|||
adapter->port_num = hw->bus.func;
|
||||
adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
|
||||
|
||||
/* Disable ASPM L1.2 on I226 devices to avoid packet loss */
|
||||
if (igc_is_device_id_i226(hw))
|
||||
pci_disable_link_state(pdev, PCIE_LINK_STATE_L1_2);
|
||||
|
||||
err = pci_save_state(pdev);
|
||||
if (err)
|
||||
goto err_ioremap;
|
||||
|
@ -7500,6 +7504,9 @@ static int __igc_resume(struct device *dev, bool rpm)
|
|||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||
pci_enable_wake(pdev, PCI_D3cold, 0);
|
||||
|
||||
if (igc_is_device_id_i226(hw))
|
||||
pci_disable_link_state(pdev, PCIE_LINK_STATE_L1_2);
|
||||
|
||||
if (igc_init_interrupt_scheme(adapter, true)) {
|
||||
netdev_err(netdev, "Unable to allocate memory for queues\n");
|
||||
return -ENOMEM;
|
||||
|
@ -7625,6 +7632,9 @@ static pci_ers_result_t igc_io_slot_reset(struct pci_dev *pdev)
|
|||
pci_enable_wake(pdev, PCI_D3hot, 0);
|
||||
pci_enable_wake(pdev, PCI_D3cold, 0);
|
||||
|
||||
if (igc_is_device_id_i226(hw))
|
||||
pci_disable_link_state_locked(pdev, PCIE_LINK_STATE_L1_2);
|
||||
|
||||
/* In case of PCI error, adapter loses its HW address
|
||||
* so we should re-assign it here.
|
||||
*/
|
||||
|
|
|
@ -3336,7 +3336,7 @@ static int niu_rbr_add_page(struct niu *np, struct rx_ring_info *rp,
|
|||
|
||||
addr = np->ops->map_page(np->device, page, 0,
|
||||
PAGE_SIZE, DMA_FROM_DEVICE);
|
||||
if (!addr) {
|
||||
if (np->ops->mapping_error(np->device, addr)) {
|
||||
__free_page(page);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
@ -6676,6 +6676,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb,
|
|||
len = skb_headlen(skb);
|
||||
mapping = np->ops->map_single(np->device, skb->data,
|
||||
len, DMA_TO_DEVICE);
|
||||
if (np->ops->mapping_error(np->device, mapping))
|
||||
goto out_drop;
|
||||
|
||||
prod = rp->prod;
|
||||
|
||||
|
@ -6717,6 +6719,8 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb,
|
|||
mapping = np->ops->map_page(np->device, skb_frag_page(frag),
|
||||
skb_frag_off(frag), len,
|
||||
DMA_TO_DEVICE);
|
||||
if (np->ops->mapping_error(np->device, mapping))
|
||||
goto out_unmap;
|
||||
|
||||
rp->tx_buffs[prod].skb = NULL;
|
||||
rp->tx_buffs[prod].mapping = mapping;
|
||||
|
@ -6741,6 +6745,19 @@ static netdev_tx_t niu_start_xmit(struct sk_buff *skb,
|
|||
out:
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
out_unmap:
|
||||
while (i--) {
|
||||
const skb_frag_t *frag;
|
||||
|
||||
prod = PREVIOUS_TX(rp, prod);
|
||||
frag = &skb_shinfo(skb)->frags[i];
|
||||
np->ops->unmap_page(np->device, rp->tx_buffs[prod].mapping,
|
||||
skb_frag_size(frag), DMA_TO_DEVICE);
|
||||
}
|
||||
|
||||
np->ops->unmap_single(np->device, rp->tx_buffs[rp->prod].mapping,
|
||||
skb_headlen(skb), DMA_TO_DEVICE);
|
||||
|
||||
out_drop:
|
||||
rp->tx_errors++;
|
||||
kfree_skb(skb);
|
||||
|
@ -9644,6 +9661,11 @@ static void niu_pci_unmap_single(struct device *dev, u64 dma_address,
|
|||
dma_unmap_single(dev, dma_address, size, direction);
|
||||
}
|
||||
|
||||
static int niu_pci_mapping_error(struct device *dev, u64 addr)
|
||||
{
|
||||
return dma_mapping_error(dev, addr);
|
||||
}
|
||||
|
||||
static const struct niu_ops niu_pci_ops = {
|
||||
.alloc_coherent = niu_pci_alloc_coherent,
|
||||
.free_coherent = niu_pci_free_coherent,
|
||||
|
@ -9651,6 +9673,7 @@ static const struct niu_ops niu_pci_ops = {
|
|||
.unmap_page = niu_pci_unmap_page,
|
||||
.map_single = niu_pci_map_single,
|
||||
.unmap_single = niu_pci_unmap_single,
|
||||
.mapping_error = niu_pci_mapping_error,
|
||||
};
|
||||
|
||||
static void niu_driver_version(void)
|
||||
|
@ -10019,6 +10042,11 @@ static void niu_phys_unmap_single(struct device *dev, u64 dma_address,
|
|||
/* Nothing to do. */
|
||||
}
|
||||
|
||||
static int niu_phys_mapping_error(struct device *dev, u64 dma_address)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static const struct niu_ops niu_phys_ops = {
|
||||
.alloc_coherent = niu_phys_alloc_coherent,
|
||||
.free_coherent = niu_phys_free_coherent,
|
||||
|
@ -10026,6 +10054,7 @@ static const struct niu_ops niu_phys_ops = {
|
|||
.unmap_page = niu_phys_unmap_page,
|
||||
.map_single = niu_phys_map_single,
|
||||
.unmap_single = niu_phys_unmap_single,
|
||||
.mapping_error = niu_phys_mapping_error,
|
||||
};
|
||||
|
||||
static int niu_of_probe(struct platform_device *op)
|
||||
|
|
|
@ -2879,6 +2879,9 @@ struct tx_ring_info {
|
|||
#define NEXT_TX(tp, index) \
|
||||
(((index) + 1) < (tp)->pending ? ((index) + 1) : 0)
|
||||
|
||||
#define PREVIOUS_TX(tp, index) \
|
||||
(((index) - 1) >= 0 ? ((index) - 1) : (((tp)->pending) - 1))
|
||||
|
||||
static inline u32 niu_tx_avail(struct tx_ring_info *tp)
|
||||
{
|
||||
return (tp->pending -
|
||||
|
@ -3140,6 +3143,7 @@ struct niu_ops {
|
|||
enum dma_data_direction direction);
|
||||
void (*unmap_single)(struct device *dev, u64 dma_address,
|
||||
size_t size, enum dma_data_direction direction);
|
||||
int (*mapping_error)(struct device *dev, u64 dma_address);
|
||||
};
|
||||
|
||||
struct niu_link_config {
|
||||
|
|
|
@ -1705,6 +1705,7 @@ static void wx_set_rss_queues(struct wx *wx)
|
|||
|
||||
clear_bit(WX_FLAG_FDIR_HASH, wx->flags);
|
||||
|
||||
wx->ring_feature[RING_F_FDIR].indices = 1;
|
||||
/* Use Flow Director in addition to RSS to ensure the best
|
||||
* distribution of flows across cores, even when an FDIR flow
|
||||
* isn't matched.
|
||||
|
@ -1746,7 +1747,7 @@ static void wx_set_num_queues(struct wx *wx)
|
|||
*/
|
||||
static int wx_acquire_msix_vectors(struct wx *wx)
|
||||
{
|
||||
struct irq_affinity affd = { .pre_vectors = 1 };
|
||||
struct irq_affinity affd = { .post_vectors = 1 };
|
||||
int nvecs, i;
|
||||
|
||||
/* We start by asking for one vector per queue pair */
|
||||
|
@ -1783,16 +1784,24 @@ static int wx_acquire_msix_vectors(struct wx *wx)
|
|||
return nvecs;
|
||||
}
|
||||
|
||||
wx->msix_entry->entry = 0;
|
||||
wx->msix_entry->vector = pci_irq_vector(wx->pdev, 0);
|
||||
nvecs -= 1;
|
||||
for (i = 0; i < nvecs; i++) {
|
||||
wx->msix_q_entries[i].entry = i;
|
||||
wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i + 1);
|
||||
wx->msix_q_entries[i].vector = pci_irq_vector(wx->pdev, i);
|
||||
}
|
||||
|
||||
wx->num_q_vectors = nvecs;
|
||||
|
||||
wx->msix_entry->entry = nvecs;
|
||||
wx->msix_entry->vector = pci_irq_vector(wx->pdev, nvecs);
|
||||
|
||||
if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags)) {
|
||||
wx->msix_entry->entry = 0;
|
||||
wx->msix_entry->vector = pci_irq_vector(wx->pdev, 0);
|
||||
wx->msix_q_entries[0].entry = 0;
|
||||
wx->msix_q_entries[0].vector = pci_irq_vector(wx->pdev, 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2291,6 +2300,8 @@ static void wx_set_ivar(struct wx *wx, s8 direction,
|
|||
|
||||
if (direction == -1) {
|
||||
/* other causes */
|
||||
if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags))
|
||||
msix_vector = 0;
|
||||
msix_vector |= WX_PX_IVAR_ALLOC_VAL;
|
||||
index = 0;
|
||||
ivar = rd32(wx, WX_PX_MISC_IVAR);
|
||||
|
@ -2299,8 +2310,6 @@ static void wx_set_ivar(struct wx *wx, s8 direction,
|
|||
wr32(wx, WX_PX_MISC_IVAR, ivar);
|
||||
} else {
|
||||
/* tx or rx causes */
|
||||
if (!(wx->mac.type == wx_mac_em && wx->num_vfs == 7))
|
||||
msix_vector += 1; /* offset for queue vectors */
|
||||
msix_vector |= WX_PX_IVAR_ALLOC_VAL;
|
||||
index = ((16 * (queue & 1)) + (8 * direction));
|
||||
ivar = rd32(wx, WX_PX_IVAR(queue >> 1));
|
||||
|
@ -2339,7 +2348,7 @@ void wx_write_eitr(struct wx_q_vector *q_vector)
|
|||
|
||||
itr_reg |= WX_PX_ITR_CNT_WDIS;
|
||||
|
||||
wr32(wx, WX_PX_ITR(v_idx + 1), itr_reg);
|
||||
wr32(wx, WX_PX_ITR(v_idx), itr_reg);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2392,9 +2401,9 @@ void wx_configure_vectors(struct wx *wx)
|
|||
wx_write_eitr(q_vector);
|
||||
}
|
||||
|
||||
wx_set_ivar(wx, -1, 0, 0);
|
||||
wx_set_ivar(wx, -1, 0, v_idx);
|
||||
if (pdev->msix_enabled)
|
||||
wr32(wx, WX_PX_ITR(0), 1950);
|
||||
wr32(wx, WX_PX_ITR(v_idx), 1950);
|
||||
}
|
||||
EXPORT_SYMBOL(wx_configure_vectors);
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ static void wx_sriov_clear_data(struct wx *wx)
|
|||
wr32m(wx, WX_PSR_VM_CTL, WX_PSR_VM_CTL_POOL_MASK, 0);
|
||||
wx->ring_feature[RING_F_VMDQ].offset = 0;
|
||||
|
||||
clear_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags);
|
||||
clear_bit(WX_FLAG_SRIOV_ENABLED, wx->flags);
|
||||
/* Disable VMDq flag so device will be set in NM mode */
|
||||
if (wx->ring_feature[RING_F_VMDQ].limit == 1)
|
||||
|
@ -78,6 +79,9 @@ static int __wx_enable_sriov(struct wx *wx, u8 num_vfs)
|
|||
set_bit(WX_FLAG_SRIOV_ENABLED, wx->flags);
|
||||
dev_info(&wx->pdev->dev, "SR-IOV enabled with %d VFs\n", num_vfs);
|
||||
|
||||
if (num_vfs == 7 && wx->mac.type == wx_mac_em)
|
||||
set_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags);
|
||||
|
||||
/* Enable VMDq flag so device will be set in VM mode */
|
||||
set_bit(WX_FLAG_VMDQ_ENABLED, wx->flags);
|
||||
if (!wx->ring_feature[RING_F_VMDQ].limit)
|
||||
|
|
|
@ -1191,6 +1191,7 @@ enum wx_pf_flags {
|
|||
WX_FLAG_VMDQ_ENABLED,
|
||||
WX_FLAG_VLAN_PROMISC,
|
||||
WX_FLAG_SRIOV_ENABLED,
|
||||
WX_FLAG_IRQ_VECTOR_SHARED,
|
||||
WX_FLAG_FDIR_CAPABLE,
|
||||
WX_FLAG_FDIR_HASH,
|
||||
WX_FLAG_FDIR_PERFECT,
|
||||
|
@ -1343,7 +1344,7 @@ struct wx {
|
|||
};
|
||||
|
||||
#define WX_INTR_ALL (~0ULL)
|
||||
#define WX_INTR_Q(i) BIT((i) + 1)
|
||||
#define WX_INTR_Q(i) BIT((i))
|
||||
|
||||
/* register operations */
|
||||
#define wr32(a, reg, value) writel((value), ((a)->hw_addr + (reg)))
|
||||
|
|
|
@ -161,7 +161,7 @@ static void ngbe_irq_enable(struct wx *wx, bool queues)
|
|||
if (queues)
|
||||
wx_intr_enable(wx, NGBE_INTR_ALL);
|
||||
else
|
||||
wx_intr_enable(wx, NGBE_INTR_MISC);
|
||||
wx_intr_enable(wx, NGBE_INTR_MISC(wx));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,7 +286,7 @@ static int ngbe_request_msix_irqs(struct wx *wx)
|
|||
* for queue. But when num_vfs == 7, vector[1] is assigned to vf6.
|
||||
* Misc and queue should reuse interrupt vector[0].
|
||||
*/
|
||||
if (wx->num_vfs == 7)
|
||||
if (test_bit(WX_FLAG_IRQ_VECTOR_SHARED, wx->flags))
|
||||
err = request_irq(wx->msix_entry->vector,
|
||||
ngbe_misc_and_queue, 0, netdev->name, wx);
|
||||
else
|
||||
|
|
|
@ -87,7 +87,7 @@
|
|||
#define NGBE_PX_MISC_IC_TIMESYNC BIT(11) /* time sync */
|
||||
|
||||
#define NGBE_INTR_ALL 0x1FF
|
||||
#define NGBE_INTR_MISC BIT(0)
|
||||
#define NGBE_INTR_MISC(A) BIT((A)->msix_entry->entry)
|
||||
|
||||
#define NGBE_PHY_CONFIG(reg_offset) (0x14000 + ((reg_offset) * 4))
|
||||
#define NGBE_CFG_LAN_SPEED 0x14440
|
||||
|
|
|
@ -294,6 +294,7 @@ static void txgbe_mac_link_up_aml(struct phylink_config *config,
|
|||
wx_fc_enable(wx, tx_pause, rx_pause);
|
||||
|
||||
txgbe_reconfig_mac(wx);
|
||||
txgbe_enable_sec_tx_path(wx);
|
||||
|
||||
txcfg = rd32(wx, TXGBE_AML_MAC_TX_CFG);
|
||||
txcfg &= ~TXGBE_AML_MAC_TX_CFG_SPEED_MASK;
|
||||
|
|
|
@ -31,7 +31,7 @@ void txgbe_irq_enable(struct wx *wx, bool queues)
|
|||
wr32(wx, WX_PX_MISC_IEN, misc_ien);
|
||||
|
||||
/* unmask interrupt */
|
||||
wx_intr_enable(wx, TXGBE_INTR_MISC);
|
||||
wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
|
||||
if (queues)
|
||||
wx_intr_enable(wx, TXGBE_INTR_QALL(wx));
|
||||
}
|
||||
|
@ -78,7 +78,6 @@ free_queue_irqs:
|
|||
free_irq(wx->msix_q_entries[vector].vector,
|
||||
wx->q_vector[vector]);
|
||||
}
|
||||
wx_reset_interrupt_capability(wx);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -132,7 +131,7 @@ static irqreturn_t txgbe_misc_irq_handle(int irq, void *data)
|
|||
txgbe->eicr = eicr;
|
||||
if (eicr & TXGBE_PX_MISC_IC_VF_MBOX) {
|
||||
wx_msg_task(txgbe->wx);
|
||||
wx_intr_enable(wx, TXGBE_INTR_MISC);
|
||||
wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
|
||||
}
|
||||
return IRQ_WAKE_THREAD;
|
||||
}
|
||||
|
@ -184,7 +183,7 @@ static irqreturn_t txgbe_misc_irq_thread_fn(int irq, void *data)
|
|||
nhandled++;
|
||||
}
|
||||
|
||||
wx_intr_enable(wx, TXGBE_INTR_MISC);
|
||||
wx_intr_enable(wx, TXGBE_INTR_MISC(wx));
|
||||
return (nhandled > 0 ? IRQ_HANDLED : IRQ_NONE);
|
||||
}
|
||||
|
||||
|
@ -211,6 +210,7 @@ void txgbe_free_misc_irq(struct txgbe *txgbe)
|
|||
free_irq(txgbe->link_irq, txgbe);
|
||||
free_irq(txgbe->misc.irq, txgbe);
|
||||
txgbe_del_irq_domain(txgbe);
|
||||
txgbe->wx->misc_irq_domain = false;
|
||||
}
|
||||
|
||||
int txgbe_setup_misc_irq(struct txgbe *txgbe)
|
||||
|
|
|
@ -458,10 +458,14 @@ static int txgbe_open(struct net_device *netdev)
|
|||
|
||||
wx_configure(wx);
|
||||
|
||||
err = txgbe_request_queue_irqs(wx);
|
||||
err = txgbe_setup_misc_irq(wx->priv);
|
||||
if (err)
|
||||
goto err_free_resources;
|
||||
|
||||
err = txgbe_request_queue_irqs(wx);
|
||||
if (err)
|
||||
goto err_free_misc_irq;
|
||||
|
||||
/* Notify the stack of the actual queue counts. */
|
||||
err = netif_set_real_num_tx_queues(netdev, wx->num_tx_queues);
|
||||
if (err)
|
||||
|
@ -479,6 +483,9 @@ static int txgbe_open(struct net_device *netdev)
|
|||
|
||||
err_free_irq:
|
||||
wx_free_irq(wx);
|
||||
err_free_misc_irq:
|
||||
txgbe_free_misc_irq(wx->priv);
|
||||
wx_reset_interrupt_capability(wx);
|
||||
err_free_resources:
|
||||
wx_free_resources(wx);
|
||||
err_reset:
|
||||
|
@ -519,6 +526,7 @@ static int txgbe_close(struct net_device *netdev)
|
|||
wx_ptp_stop(wx);
|
||||
txgbe_down(wx);
|
||||
wx_free_irq(wx);
|
||||
txgbe_free_misc_irq(wx->priv);
|
||||
wx_free_resources(wx);
|
||||
txgbe_fdir_filter_exit(wx);
|
||||
wx_control_hw(wx, false);
|
||||
|
@ -564,7 +572,6 @@ static void txgbe_shutdown(struct pci_dev *pdev)
|
|||
int txgbe_setup_tc(struct net_device *dev, u8 tc)
|
||||
{
|
||||
struct wx *wx = netdev_priv(dev);
|
||||
struct txgbe *txgbe = wx->priv;
|
||||
|
||||
/* Hardware has to reinitialize queues and interrupts to
|
||||
* match packet buffer alignment. Unfortunately, the
|
||||
|
@ -575,7 +582,6 @@ int txgbe_setup_tc(struct net_device *dev, u8 tc)
|
|||
else
|
||||
txgbe_reset(wx);
|
||||
|
||||
txgbe_free_misc_irq(txgbe);
|
||||
wx_clear_interrupt_scheme(wx);
|
||||
|
||||
if (tc)
|
||||
|
@ -584,7 +590,6 @@ int txgbe_setup_tc(struct net_device *dev, u8 tc)
|
|||
netdev_reset_tc(dev);
|
||||
|
||||
wx_init_interrupt_scheme(wx);
|
||||
txgbe_setup_misc_irq(txgbe);
|
||||
|
||||
if (netif_running(dev))
|
||||
txgbe_open(dev);
|
||||
|
@ -882,13 +887,9 @@ static int txgbe_probe(struct pci_dev *pdev,
|
|||
|
||||
txgbe_init_fdir(txgbe);
|
||||
|
||||
err = txgbe_setup_misc_irq(txgbe);
|
||||
if (err)
|
||||
goto err_release_hw;
|
||||
|
||||
err = txgbe_init_phy(txgbe);
|
||||
if (err)
|
||||
goto err_free_misc_irq;
|
||||
goto err_release_hw;
|
||||
|
||||
err = register_netdev(netdev);
|
||||
if (err)
|
||||
|
@ -916,8 +917,6 @@ static int txgbe_probe(struct pci_dev *pdev,
|
|||
|
||||
err_remove_phy:
|
||||
txgbe_remove_phy(txgbe);
|
||||
err_free_misc_irq:
|
||||
txgbe_free_misc_irq(txgbe);
|
||||
err_release_hw:
|
||||
wx_clear_interrupt_scheme(wx);
|
||||
wx_control_hw(wx, false);
|
||||
|
@ -957,7 +956,6 @@ static void txgbe_remove(struct pci_dev *pdev)
|
|||
unregister_netdev(netdev);
|
||||
|
||||
txgbe_remove_phy(txgbe);
|
||||
txgbe_free_misc_irq(txgbe);
|
||||
wx_free_isb_resources(wx);
|
||||
|
||||
pci_release_selected_regions(pdev,
|
||||
|
|
|
@ -302,8 +302,8 @@ struct txgbe_fdir_filter {
|
|||
#define TXGBE_DEFAULT_RX_WORK 128
|
||||
#endif
|
||||
|
||||
#define TXGBE_INTR_MISC BIT(0)
|
||||
#define TXGBE_INTR_QALL(A) GENMASK((A)->num_q_vectors, 1)
|
||||
#define TXGBE_INTR_MISC(A) BIT((A)->num_q_vectors)
|
||||
#define TXGBE_INTR_QALL(A) (TXGBE_INTR_MISC(A) - 1)
|
||||
|
||||
#define TXGBE_MAX_EITR GENMASK(11, 3)
|
||||
|
||||
|
|
|
@ -4567,8 +4567,6 @@ static void lan78xx_disconnect(struct usb_interface *intf)
|
|||
if (!dev)
|
||||
return;
|
||||
|
||||
netif_napi_del(&dev->napi);
|
||||
|
||||
udev = interface_to_usbdev(intf);
|
||||
net = dev->net;
|
||||
|
||||
|
|
|
@ -778,6 +778,26 @@ static unsigned int mergeable_ctx_to_truesize(void *mrg_ctx)
|
|||
return (unsigned long)mrg_ctx & ((1 << MRG_CTX_HEADER_SHIFT) - 1);
|
||||
}
|
||||
|
||||
static int check_mergeable_len(struct net_device *dev, void *mrg_ctx,
|
||||
unsigned int len)
|
||||
{
|
||||
unsigned int headroom, tailroom, room, truesize;
|
||||
|
||||
truesize = mergeable_ctx_to_truesize(mrg_ctx);
|
||||
headroom = mergeable_ctx_to_headroom(mrg_ctx);
|
||||
tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
|
||||
room = SKB_DATA_ALIGN(headroom + tailroom);
|
||||
|
||||
if (len > truesize - room) {
|
||||
pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
|
||||
dev->name, len, (unsigned long)(truesize - room));
|
||||
DEV_STATS_INC(dev, rx_length_errors);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct sk_buff *virtnet_build_skb(void *buf, unsigned int buflen,
|
||||
unsigned int headroom,
|
||||
unsigned int len)
|
||||
|
@ -1084,7 +1104,7 @@ static bool tx_may_stop(struct virtnet_info *vi,
|
|||
* Since most packets only take 1 or 2 ring slots, stopping the queue
|
||||
* early means 16 slots are typically wasted.
|
||||
*/
|
||||
if (sq->vq->num_free < 2+MAX_SKB_FRAGS) {
|
||||
if (sq->vq->num_free < MAX_SKB_FRAGS + 2) {
|
||||
struct netdev_queue *txq = netdev_get_tx_queue(dev, qnum);
|
||||
|
||||
netif_tx_stop_queue(txq);
|
||||
|
@ -1116,7 +1136,7 @@ static void check_sq_full_and_disable(struct virtnet_info *vi,
|
|||
} else if (unlikely(!virtqueue_enable_cb_delayed(sq->vq))) {
|
||||
/* More just got used, free them then recheck. */
|
||||
free_old_xmit(sq, txq, false);
|
||||
if (sq->vq->num_free >= 2+MAX_SKB_FRAGS) {
|
||||
if (sq->vq->num_free >= MAX_SKB_FRAGS + 2) {
|
||||
netif_start_subqueue(dev, qnum);
|
||||
u64_stats_update_begin(&sq->stats.syncp);
|
||||
u64_stats_inc(&sq->stats.wake);
|
||||
|
@ -1127,15 +1147,29 @@ static void check_sq_full_and_disable(struct virtnet_info *vi,
|
|||
}
|
||||
}
|
||||
|
||||
/* Note that @len is the length of received data without virtio header */
|
||||
static struct xdp_buff *buf_to_xdp(struct virtnet_info *vi,
|
||||
struct receive_queue *rq, void *buf, u32 len)
|
||||
struct receive_queue *rq, void *buf,
|
||||
u32 len, bool first_buf)
|
||||
{
|
||||
struct xdp_buff *xdp;
|
||||
u32 bufsize;
|
||||
|
||||
xdp = (struct xdp_buff *)buf;
|
||||
|
||||
bufsize = xsk_pool_get_rx_frame_size(rq->xsk_pool) + vi->hdr_len;
|
||||
/* In virtnet_add_recvbuf_xsk, we use part of XDP_PACKET_HEADROOM for
|
||||
* virtio header and ask the vhost to fill data from
|
||||
* hard_start + XDP_PACKET_HEADROOM - vi->hdr_len
|
||||
* The first buffer has virtio header so the remaining region for frame
|
||||
* data is
|
||||
* xsk_pool_get_rx_frame_size()
|
||||
* While other buffers than the first one do not have virtio header, so
|
||||
* the maximum frame data's length can be
|
||||
* xsk_pool_get_rx_frame_size() + vi->hdr_len
|
||||
*/
|
||||
bufsize = xsk_pool_get_rx_frame_size(rq->xsk_pool);
|
||||
if (!first_buf)
|
||||
bufsize += vi->hdr_len;
|
||||
|
||||
if (unlikely(len > bufsize)) {
|
||||
pr_debug("%s: rx error: len %u exceeds truesize %u\n",
|
||||
|
@ -1260,7 +1294,7 @@ static int xsk_append_merge_buffer(struct virtnet_info *vi,
|
|||
|
||||
u64_stats_add(&stats->bytes, len);
|
||||
|
||||
xdp = buf_to_xdp(vi, rq, buf, len);
|
||||
xdp = buf_to_xdp(vi, rq, buf, len, false);
|
||||
if (!xdp)
|
||||
goto err;
|
||||
|
||||
|
@ -1358,7 +1392,7 @@ static void virtnet_receive_xsk_buf(struct virtnet_info *vi, struct receive_queu
|
|||
|
||||
u64_stats_add(&stats->bytes, len);
|
||||
|
||||
xdp = buf_to_xdp(vi, rq, buf, len);
|
||||
xdp = buf_to_xdp(vi, rq, buf, len, true);
|
||||
if (!xdp)
|
||||
return;
|
||||
|
||||
|
@ -1797,7 +1831,8 @@ static unsigned int virtnet_get_headroom(struct virtnet_info *vi)
|
|||
* across multiple buffers (num_buf > 1), and we make sure buffers
|
||||
* have enough headroom.
|
||||
*/
|
||||
static struct page *xdp_linearize_page(struct receive_queue *rq,
|
||||
static struct page *xdp_linearize_page(struct net_device *dev,
|
||||
struct receive_queue *rq,
|
||||
int *num_buf,
|
||||
struct page *p,
|
||||
int offset,
|
||||
|
@ -1817,18 +1852,27 @@ static struct page *xdp_linearize_page(struct receive_queue *rq,
|
|||
memcpy(page_address(page) + page_off, page_address(p) + offset, *len);
|
||||
page_off += *len;
|
||||
|
||||
/* Only mergeable mode can go inside this while loop. In small mode,
|
||||
* *num_buf == 1, so it cannot go inside.
|
||||
*/
|
||||
while (--*num_buf) {
|
||||
unsigned int buflen;
|
||||
void *buf;
|
||||
void *ctx;
|
||||
int off;
|
||||
|
||||
buf = virtnet_rq_get_buf(rq, &buflen, NULL);
|
||||
buf = virtnet_rq_get_buf(rq, &buflen, &ctx);
|
||||
if (unlikely(!buf))
|
||||
goto err_buf;
|
||||
|
||||
p = virt_to_head_page(buf);
|
||||
off = buf - page_address(p);
|
||||
|
||||
if (check_mergeable_len(dev, ctx, buflen)) {
|
||||
put_page(p);
|
||||
goto err_buf;
|
||||
}
|
||||
|
||||
/* guard against a misconfigured or uncooperative backend that
|
||||
* is sending packet larger than the MTU.
|
||||
*/
|
||||
|
@ -1917,7 +1961,7 @@ static struct sk_buff *receive_small_xdp(struct net_device *dev,
|
|||
headroom = vi->hdr_len + header_offset;
|
||||
buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
|
||||
SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
|
||||
xdp_page = xdp_linearize_page(rq, &num_buf, page,
|
||||
xdp_page = xdp_linearize_page(dev, rq, &num_buf, page,
|
||||
offset, header_offset,
|
||||
&tlen);
|
||||
if (!xdp_page)
|
||||
|
@ -2126,10 +2170,9 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
|
|||
struct virtnet_rq_stats *stats)
|
||||
{
|
||||
struct virtio_net_hdr_mrg_rxbuf *hdr = buf;
|
||||
unsigned int headroom, tailroom, room;
|
||||
unsigned int truesize, cur_frag_size;
|
||||
struct skb_shared_info *shinfo;
|
||||
unsigned int xdp_frags_truesz = 0;
|
||||
unsigned int truesize;
|
||||
struct page *page;
|
||||
skb_frag_t *frag;
|
||||
int offset;
|
||||
|
@ -2172,21 +2215,14 @@ static int virtnet_build_xdp_buff_mrg(struct net_device *dev,
|
|||
page = virt_to_head_page(buf);
|
||||
offset = buf - page_address(page);
|
||||
|
||||
truesize = mergeable_ctx_to_truesize(ctx);
|
||||
headroom = mergeable_ctx_to_headroom(ctx);
|
||||
tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
|
||||
room = SKB_DATA_ALIGN(headroom + tailroom);
|
||||
|
||||
cur_frag_size = truesize;
|
||||
xdp_frags_truesz += cur_frag_size;
|
||||
if (unlikely(len > truesize - room || cur_frag_size > PAGE_SIZE)) {
|
||||
if (check_mergeable_len(dev, ctx, len)) {
|
||||
put_page(page);
|
||||
pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
|
||||
dev->name, len, (unsigned long)(truesize - room));
|
||||
DEV_STATS_INC(dev, rx_length_errors);
|
||||
goto err;
|
||||
}
|
||||
|
||||
truesize = mergeable_ctx_to_truesize(ctx);
|
||||
xdp_frags_truesz += truesize;
|
||||
|
||||
frag = &shinfo->frags[shinfo->nr_frags++];
|
||||
skb_frag_fill_page_desc(frag, page, offset, len);
|
||||
if (page_is_pfmemalloc(page))
|
||||
|
@ -2252,7 +2288,7 @@ static void *mergeable_xdp_get_buf(struct virtnet_info *vi,
|
|||
*/
|
||||
if (!xdp_prog->aux->xdp_has_frags) {
|
||||
/* linearize data for XDP */
|
||||
xdp_page = xdp_linearize_page(rq, num_buf,
|
||||
xdp_page = xdp_linearize_page(vi->dev, rq, num_buf,
|
||||
*page, offset,
|
||||
XDP_PACKET_HEADROOM,
|
||||
len);
|
||||
|
@ -2400,18 +2436,12 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
|
|||
struct sk_buff *head_skb, *curr_skb;
|
||||
unsigned int truesize = mergeable_ctx_to_truesize(ctx);
|
||||
unsigned int headroom = mergeable_ctx_to_headroom(ctx);
|
||||
unsigned int tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
|
||||
unsigned int room = SKB_DATA_ALIGN(headroom + tailroom);
|
||||
|
||||
head_skb = NULL;
|
||||
u64_stats_add(&stats->bytes, len - vi->hdr_len);
|
||||
|
||||
if (unlikely(len > truesize - room)) {
|
||||
pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
|
||||
dev->name, len, (unsigned long)(truesize - room));
|
||||
DEV_STATS_INC(dev, rx_length_errors);
|
||||
if (check_mergeable_len(dev, ctx, len))
|
||||
goto err_skb;
|
||||
}
|
||||
|
||||
if (unlikely(vi->xdp_enabled)) {
|
||||
struct bpf_prog *xdp_prog;
|
||||
|
@ -2446,17 +2476,10 @@ static struct sk_buff *receive_mergeable(struct net_device *dev,
|
|||
u64_stats_add(&stats->bytes, len);
|
||||
page = virt_to_head_page(buf);
|
||||
|
||||
truesize = mergeable_ctx_to_truesize(ctx);
|
||||
headroom = mergeable_ctx_to_headroom(ctx);
|
||||
tailroom = headroom ? sizeof(struct skb_shared_info) : 0;
|
||||
room = SKB_DATA_ALIGN(headroom + tailroom);
|
||||
if (unlikely(len > truesize - room)) {
|
||||
pr_debug("%s: rx error: len %u exceeds truesize %lu\n",
|
||||
dev->name, len, (unsigned long)(truesize - room));
|
||||
DEV_STATS_INC(dev, rx_length_errors);
|
||||
if (check_mergeable_len(dev, ctx, len))
|
||||
goto err_skb;
|
||||
}
|
||||
|
||||
truesize = mergeable_ctx_to_truesize(ctx);
|
||||
curr_skb = virtnet_skb_append_frag(head_skb, curr_skb, page,
|
||||
buf, len, truesize);
|
||||
if (!curr_skb)
|
||||
|
@ -2998,7 +3021,7 @@ static void virtnet_poll_cleantx(struct receive_queue *rq, int budget)
|
|||
free_old_xmit(sq, txq, !!budget);
|
||||
} while (unlikely(!virtqueue_enable_cb_delayed(sq->vq)));
|
||||
|
||||
if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) {
|
||||
if (sq->vq->num_free >= MAX_SKB_FRAGS + 2) {
|
||||
if (netif_tx_queue_stopped(txq)) {
|
||||
u64_stats_update_begin(&sq->stats.syncp);
|
||||
u64_stats_inc(&sq->stats.wake);
|
||||
|
@ -3195,7 +3218,7 @@ static int virtnet_poll_tx(struct napi_struct *napi, int budget)
|
|||
else
|
||||
free_old_xmit(sq, txq, !!budget);
|
||||
|
||||
if (sq->vq->num_free >= 2 + MAX_SKB_FRAGS) {
|
||||
if (sq->vq->num_free >= MAX_SKB_FRAGS + 2) {
|
||||
if (netif_tx_queue_stopped(txq)) {
|
||||
u64_stats_update_begin(&sq->stats.syncp);
|
||||
u64_stats_inc(&sq->stats.wake);
|
||||
|
@ -3481,6 +3504,12 @@ static int virtnet_tx_resize(struct virtnet_info *vi, struct send_queue *sq,
|
|||
{
|
||||
int qindex, err;
|
||||
|
||||
if (ring_num <= MAX_SKB_FRAGS + 2) {
|
||||
netdev_err(vi->dev, "tx size (%d) cannot be smaller than %d\n",
|
||||
ring_num, MAX_SKB_FRAGS + 2);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
qindex = sq - vi->sq;
|
||||
|
||||
virtnet_tx_pause(vi, sq);
|
||||
|
|
|
@ -2797,7 +2797,7 @@ int virtqueue_resize(struct virtqueue *_vq, u32 num,
|
|||
void (*recycle_done)(struct virtqueue *vq))
|
||||
{
|
||||
struct vring_virtqueue *vq = to_vvq(_vq);
|
||||
int err;
|
||||
int err, err_reset;
|
||||
|
||||
if (num > vq->vq.num_max)
|
||||
return -E2BIG;
|
||||
|
@ -2819,7 +2819,11 @@ int virtqueue_resize(struct virtqueue *_vq, u32 num,
|
|||
else
|
||||
err = virtqueue_resize_split(_vq, num);
|
||||
|
||||
return virtqueue_enable_after_reset(_vq);
|
||||
err_reset = virtqueue_enable_after_reset(_vq);
|
||||
if (err_reset)
|
||||
return err_reset;
|
||||
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(virtqueue_resize);
|
||||
|
||||
|
|
|
@ -899,8 +899,10 @@ static int check_expect_hints_stats(struct objagg_hints *objagg_hints,
|
|||
int err;
|
||||
|
||||
stats = objagg_hints_stats_get(objagg_hints);
|
||||
if (IS_ERR(stats))
|
||||
if (IS_ERR(stats)) {
|
||||
*errmsg = "objagg_hints_stats_get() failed.";
|
||||
return PTR_ERR(stats);
|
||||
}
|
||||
err = __check_expect_stats(stats, expect_stats, errmsg);
|
||||
objagg_stats_put(stats);
|
||||
return err;
|
||||
|
|
|
@ -2150,40 +2150,6 @@ static u8 hci_cc_set_adv_param(struct hci_dev *hdev, void *data,
|
|||
return rp->status;
|
||||
}
|
||||
|
||||
static u8 hci_cc_set_ext_adv_param(struct hci_dev *hdev, void *data,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct hci_rp_le_set_ext_adv_params *rp = data;
|
||||
struct hci_cp_le_set_ext_adv_params *cp;
|
||||
struct adv_info *adv_instance;
|
||||
|
||||
bt_dev_dbg(hdev, "status 0x%2.2x", rp->status);
|
||||
|
||||
if (rp->status)
|
||||
return rp->status;
|
||||
|
||||
cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS);
|
||||
if (!cp)
|
||||
return rp->status;
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
hdev->adv_addr_type = cp->own_addr_type;
|
||||
if (!cp->handle) {
|
||||
/* Store in hdev for instance 0 */
|
||||
hdev->adv_tx_power = rp->tx_power;
|
||||
} else {
|
||||
adv_instance = hci_find_adv_instance(hdev, cp->handle);
|
||||
if (adv_instance)
|
||||
adv_instance->tx_power = rp->tx_power;
|
||||
}
|
||||
/* Update adv data as tx power is known now */
|
||||
hci_update_adv_data(hdev, cp->handle);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
|
||||
return rp->status;
|
||||
}
|
||||
|
||||
static u8 hci_cc_read_rssi(struct hci_dev *hdev, void *data,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
|
@ -4164,8 +4130,6 @@ static const struct hci_cc {
|
|||
HCI_CC(HCI_OP_LE_READ_NUM_SUPPORTED_ADV_SETS,
|
||||
hci_cc_le_read_num_adv_sets,
|
||||
sizeof(struct hci_rp_le_read_num_supported_adv_sets)),
|
||||
HCI_CC(HCI_OP_LE_SET_EXT_ADV_PARAMS, hci_cc_set_ext_adv_param,
|
||||
sizeof(struct hci_rp_le_set_ext_adv_params)),
|
||||
HCI_CC_STATUS(HCI_OP_LE_SET_EXT_ADV_ENABLE,
|
||||
hci_cc_le_set_ext_adv_enable),
|
||||
HCI_CC_STATUS(HCI_OP_LE_SET_ADV_SET_RAND_ADDR,
|
||||
|
|
|
@ -1205,9 +1205,126 @@ static int hci_set_adv_set_random_addr_sync(struct hci_dev *hdev, u8 instance,
|
|||
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
|
||||
}
|
||||
|
||||
static int
|
||||
hci_set_ext_adv_params_sync(struct hci_dev *hdev, struct adv_info *adv,
|
||||
const struct hci_cp_le_set_ext_adv_params *cp,
|
||||
struct hci_rp_le_set_ext_adv_params *rp)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS, sizeof(*cp),
|
||||
cp, HCI_CMD_TIMEOUT);
|
||||
|
||||
/* If command return a status event, skb will be set to -ENODATA */
|
||||
if (skb == ERR_PTR(-ENODATA))
|
||||
return 0;
|
||||
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Opcode 0x%4.4x failed: %ld",
|
||||
HCI_OP_LE_SET_EXT_ADV_PARAMS, PTR_ERR(skb));
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
if (skb->len != sizeof(*rp)) {
|
||||
bt_dev_err(hdev, "Invalid response length for 0x%4.4x: %u",
|
||||
HCI_OP_LE_SET_EXT_ADV_PARAMS, skb->len);
|
||||
kfree_skb(skb);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
memcpy(rp, skb->data, sizeof(*rp));
|
||||
kfree_skb(skb);
|
||||
|
||||
if (!rp->status) {
|
||||
hdev->adv_addr_type = cp->own_addr_type;
|
||||
if (!cp->handle) {
|
||||
/* Store in hdev for instance 0 */
|
||||
hdev->adv_tx_power = rp->tx_power;
|
||||
} else if (adv) {
|
||||
adv->tx_power = rp->tx_power;
|
||||
}
|
||||
}
|
||||
|
||||
return rp->status;
|
||||
}
|
||||
|
||||
static int hci_set_ext_adv_data_sync(struct hci_dev *hdev, u8 instance)
|
||||
{
|
||||
DEFINE_FLEX(struct hci_cp_le_set_ext_adv_data, pdu, data, length,
|
||||
HCI_MAX_EXT_AD_LENGTH);
|
||||
u8 len;
|
||||
struct adv_info *adv = NULL;
|
||||
int err;
|
||||
|
||||
if (instance) {
|
||||
adv = hci_find_adv_instance(hdev, instance);
|
||||
if (!adv || !adv->adv_data_changed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = eir_create_adv_data(hdev, instance, pdu->data,
|
||||
HCI_MAX_EXT_AD_LENGTH);
|
||||
|
||||
pdu->length = len;
|
||||
pdu->handle = adv ? adv->handle : instance;
|
||||
pdu->operation = LE_SET_ADV_DATA_OP_COMPLETE;
|
||||
pdu->frag_pref = LE_SET_ADV_DATA_NO_FRAG;
|
||||
|
||||
err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_DATA,
|
||||
struct_size(pdu, data, len), pdu,
|
||||
HCI_CMD_TIMEOUT);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Update data if the command succeed */
|
||||
if (adv) {
|
||||
adv->adv_data_changed = false;
|
||||
} else {
|
||||
memcpy(hdev->adv_data, pdu->data, len);
|
||||
hdev->adv_data_len = len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hci_set_adv_data_sync(struct hci_dev *hdev, u8 instance)
|
||||
{
|
||||
struct hci_cp_le_set_adv_data cp;
|
||||
u8 len;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
|
||||
len = eir_create_adv_data(hdev, instance, cp.data, sizeof(cp.data));
|
||||
|
||||
/* There's nothing to do if the data hasn't changed */
|
||||
if (hdev->adv_data_len == len &&
|
||||
memcmp(cp.data, hdev->adv_data, len) == 0)
|
||||
return 0;
|
||||
|
||||
memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
|
||||
hdev->adv_data_len = len;
|
||||
|
||||
cp.length = len;
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_DATA,
|
||||
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
|
||||
}
|
||||
|
||||
int hci_update_adv_data_sync(struct hci_dev *hdev, u8 instance)
|
||||
{
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
||||
return 0;
|
||||
|
||||
if (ext_adv_capable(hdev))
|
||||
return hci_set_ext_adv_data_sync(hdev, instance);
|
||||
|
||||
return hci_set_adv_data_sync(hdev, instance);
|
||||
}
|
||||
|
||||
int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
|
||||
{
|
||||
struct hci_cp_le_set_ext_adv_params cp;
|
||||
struct hci_rp_le_set_ext_adv_params rp;
|
||||
bool connectable;
|
||||
u32 flags;
|
||||
bdaddr_t random_addr;
|
||||
|
@ -1316,8 +1433,12 @@ int hci_setup_ext_adv_instance_sync(struct hci_dev *hdev, u8 instance)
|
|||
cp.secondary_phy = HCI_ADV_PHY_1M;
|
||||
}
|
||||
|
||||
err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS,
|
||||
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
|
||||
err = hci_set_ext_adv_params_sync(hdev, adv, &cp, &rp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Update adv data as tx power is known now */
|
||||
err = hci_set_ext_adv_data_sync(hdev, cp.handle);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
@ -1822,79 +1943,6 @@ int hci_le_terminate_big_sync(struct hci_dev *hdev, u8 handle, u8 reason)
|
|||
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
|
||||
}
|
||||
|
||||
static int hci_set_ext_adv_data_sync(struct hci_dev *hdev, u8 instance)
|
||||
{
|
||||
DEFINE_FLEX(struct hci_cp_le_set_ext_adv_data, pdu, data, length,
|
||||
HCI_MAX_EXT_AD_LENGTH);
|
||||
u8 len;
|
||||
struct adv_info *adv = NULL;
|
||||
int err;
|
||||
|
||||
if (instance) {
|
||||
adv = hci_find_adv_instance(hdev, instance);
|
||||
if (!adv || !adv->adv_data_changed)
|
||||
return 0;
|
||||
}
|
||||
|
||||
len = eir_create_adv_data(hdev, instance, pdu->data,
|
||||
HCI_MAX_EXT_AD_LENGTH);
|
||||
|
||||
pdu->length = len;
|
||||
pdu->handle = adv ? adv->handle : instance;
|
||||
pdu->operation = LE_SET_ADV_DATA_OP_COMPLETE;
|
||||
pdu->frag_pref = LE_SET_ADV_DATA_NO_FRAG;
|
||||
|
||||
err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_DATA,
|
||||
struct_size(pdu, data, len), pdu,
|
||||
HCI_CMD_TIMEOUT);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Update data if the command succeed */
|
||||
if (adv) {
|
||||
adv->adv_data_changed = false;
|
||||
} else {
|
||||
memcpy(hdev->adv_data, pdu->data, len);
|
||||
hdev->adv_data_len = len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hci_set_adv_data_sync(struct hci_dev *hdev, u8 instance)
|
||||
{
|
||||
struct hci_cp_le_set_adv_data cp;
|
||||
u8 len;
|
||||
|
||||
memset(&cp, 0, sizeof(cp));
|
||||
|
||||
len = eir_create_adv_data(hdev, instance, cp.data, sizeof(cp.data));
|
||||
|
||||
/* There's nothing to do if the data hasn't changed */
|
||||
if (hdev->adv_data_len == len &&
|
||||
memcmp(cp.data, hdev->adv_data, len) == 0)
|
||||
return 0;
|
||||
|
||||
memcpy(hdev->adv_data, cp.data, sizeof(cp.data));
|
||||
hdev->adv_data_len = len;
|
||||
|
||||
cp.length = len;
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_DATA,
|
||||
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
|
||||
}
|
||||
|
||||
int hci_update_adv_data_sync(struct hci_dev *hdev, u8 instance)
|
||||
{
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_ENABLED))
|
||||
return 0;
|
||||
|
||||
if (ext_adv_capable(hdev))
|
||||
return hci_set_ext_adv_data_sync(hdev, instance);
|
||||
|
||||
return hci_set_adv_data_sync(hdev, instance);
|
||||
}
|
||||
|
||||
int hci_schedule_adv_instance_sync(struct hci_dev *hdev, u8 instance,
|
||||
bool force)
|
||||
{
|
||||
|
@ -1970,13 +2018,10 @@ static int hci_clear_adv_sets_sync(struct hci_dev *hdev, struct sock *sk)
|
|||
static int hci_clear_adv_sync(struct hci_dev *hdev, struct sock *sk, bool force)
|
||||
{
|
||||
struct adv_info *adv, *n;
|
||||
int err = 0;
|
||||
|
||||
if (ext_adv_capable(hdev))
|
||||
/* Remove all existing sets */
|
||||
err = hci_clear_adv_sets_sync(hdev, sk);
|
||||
if (ext_adv_capable(hdev))
|
||||
return err;
|
||||
return hci_clear_adv_sets_sync(hdev, sk);
|
||||
|
||||
/* This is safe as long as there is no command send while the lock is
|
||||
* held.
|
||||
|
@ -2004,13 +2049,11 @@ static int hci_clear_adv_sync(struct hci_dev *hdev, struct sock *sk, bool force)
|
|||
static int hci_remove_adv_sync(struct hci_dev *hdev, u8 instance,
|
||||
struct sock *sk)
|
||||
{
|
||||
int err = 0;
|
||||
int err;
|
||||
|
||||
/* If we use extended advertising, instance has to be removed first. */
|
||||
if (ext_adv_capable(hdev))
|
||||
err = hci_remove_ext_adv_instance_sync(hdev, instance, sk);
|
||||
if (ext_adv_capable(hdev))
|
||||
return err;
|
||||
return hci_remove_ext_adv_instance_sync(hdev, instance, sk);
|
||||
|
||||
/* This is safe as long as there is no command send while the lock is
|
||||
* held.
|
||||
|
@ -2109,16 +2152,13 @@ int hci_read_tx_power_sync(struct hci_dev *hdev, __le16 handle, u8 type)
|
|||
int hci_disable_advertising_sync(struct hci_dev *hdev)
|
||||
{
|
||||
u8 enable = 0x00;
|
||||
int err = 0;
|
||||
|
||||
/* If controller is not advertising we are done. */
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_ADV))
|
||||
return 0;
|
||||
|
||||
if (ext_adv_capable(hdev))
|
||||
err = hci_disable_ext_adv_instance_sync(hdev, 0x00);
|
||||
if (ext_adv_capable(hdev))
|
||||
return err;
|
||||
return hci_disable_ext_adv_instance_sync(hdev, 0x00);
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_ADV_ENABLE,
|
||||
sizeof(enable), &enable, HCI_CMD_TIMEOUT);
|
||||
|
@ -2481,6 +2521,10 @@ static int hci_pause_advertising_sync(struct hci_dev *hdev)
|
|||
int err;
|
||||
int old_state;
|
||||
|
||||
/* If controller is not advertising we are done. */
|
||||
if (!hci_dev_test_flag(hdev, HCI_LE_ADV))
|
||||
return 0;
|
||||
|
||||
/* If already been paused there is nothing to do. */
|
||||
if (hdev->advertising_paused)
|
||||
return 0;
|
||||
|
@ -6277,6 +6321,7 @@ static int hci_le_ext_directed_advertising_sync(struct hci_dev *hdev,
|
|||
struct hci_conn *conn)
|
||||
{
|
||||
struct hci_cp_le_set_ext_adv_params cp;
|
||||
struct hci_rp_le_set_ext_adv_params rp;
|
||||
int err;
|
||||
bdaddr_t random_addr;
|
||||
u8 own_addr_type;
|
||||
|
@ -6318,8 +6363,12 @@ static int hci_le_ext_directed_advertising_sync(struct hci_dev *hdev,
|
|||
if (err)
|
||||
return err;
|
||||
|
||||
err = __hci_cmd_sync_status(hdev, HCI_OP_LE_SET_EXT_ADV_PARAMS,
|
||||
sizeof(cp), &cp, HCI_CMD_TIMEOUT);
|
||||
err = hci_set_ext_adv_params_sync(hdev, NULL, &cp, &rp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* Update adv data as tx power is known now */
|
||||
err = hci_set_ext_adv_data_sync(hdev, cp.handle);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
|
|
|
@ -1080,7 +1080,8 @@ static int mesh_send_done_sync(struct hci_dev *hdev, void *data)
|
|||
struct mgmt_mesh_tx *mesh_tx;
|
||||
|
||||
hci_dev_clear_flag(hdev, HCI_MESH_SENDING);
|
||||
hci_disable_advertising_sync(hdev);
|
||||
if (list_empty(&hdev->adv_instances))
|
||||
hci_disable_advertising_sync(hdev);
|
||||
mesh_tx = mgmt_mesh_next(hdev, NULL);
|
||||
|
||||
if (mesh_tx)
|
||||
|
@ -2153,6 +2154,9 @@ static int set_mesh_sync(struct hci_dev *hdev, void *data)
|
|||
else
|
||||
hci_dev_clear_flag(hdev, HCI_MESH);
|
||||
|
||||
hdev->le_scan_interval = __le16_to_cpu(cp->period);
|
||||
hdev->le_scan_window = __le16_to_cpu(cp->window);
|
||||
|
||||
len -= sizeof(*cp);
|
||||
|
||||
/* If filters don't fit, forward all adv pkts */
|
||||
|
@ -2167,6 +2171,7 @@ static int set_mesh(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|||
{
|
||||
struct mgmt_cp_set_mesh *cp = data;
|
||||
struct mgmt_pending_cmd *cmd;
|
||||
__u16 period, window;
|
||||
int err = 0;
|
||||
|
||||
bt_dev_dbg(hdev, "sock %p", sk);
|
||||
|
@ -2180,6 +2185,23 @@ static int set_mesh(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
|
|||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
/* Keep allowed ranges in sync with set_scan_params() */
|
||||
period = __le16_to_cpu(cp->period);
|
||||
|
||||
if (period < 0x0004 || period > 0x4000)
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
window = __le16_to_cpu(cp->window);
|
||||
|
||||
if (window < 0x0004 || window > 0x4000)
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
if (window > period)
|
||||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_MESH_RECEIVER,
|
||||
MGMT_STATUS_INVALID_PARAMS);
|
||||
|
||||
hci_dev_lock(hdev);
|
||||
|
||||
cmd = mgmt_pending_add(sk, MGMT_OP_SET_MESH_RECEIVER, hdev, data, len);
|
||||
|
@ -6432,6 +6454,7 @@ static int set_scan_params(struct sock *sk, struct hci_dev *hdev,
|
|||
return mgmt_cmd_status(sk, hdev->id, MGMT_OP_SET_SCAN_PARAMS,
|
||||
MGMT_STATUS_NOT_SUPPORTED);
|
||||
|
||||
/* Keep allowed ranges in sync with set_mesh() */
|
||||
interval = __le16_to_cpu(cp->interval);
|
||||
|
||||
if (interval < 0x0004 || interval > 0x4000)
|
||||
|
|
|
@ -319,8 +319,8 @@ static int ip_rcv_finish_core(struct net *net,
|
|||
const struct sk_buff *hint)
|
||||
{
|
||||
const struct iphdr *iph = ip_hdr(skb);
|
||||
int err, drop_reason;
|
||||
struct rtable *rt;
|
||||
int drop_reason;
|
||||
|
||||
if (ip_can_use_hint(skb, iph, hint)) {
|
||||
drop_reason = ip_route_use_hint(skb, iph->daddr, iph->saddr,
|
||||
|
@ -345,9 +345,10 @@ static int ip_rcv_finish_core(struct net *net,
|
|||
break;
|
||||
case IPPROTO_UDP:
|
||||
if (READ_ONCE(net->ipv4.sysctl_udp_early_demux)) {
|
||||
err = udp_v4_early_demux(skb);
|
||||
if (unlikely(err))
|
||||
drop_reason = udp_v4_early_demux(skb);
|
||||
if (unlikely(drop_reason))
|
||||
goto drop_error;
|
||||
drop_reason = SKB_DROP_REASON_NOT_SPECIFIED;
|
||||
|
||||
/* must reload iph, skb->head might have changed */
|
||||
iph = ip_hdr(skb);
|
||||
|
|
|
@ -497,22 +497,15 @@ void rose_rt_device_down(struct net_device *dev)
|
|||
t = rose_node;
|
||||
rose_node = rose_node->next;
|
||||
|
||||
for (i = 0; i < t->count; i++) {
|
||||
for (i = t->count - 1; i >= 0; i--) {
|
||||
if (t->neighbour[i] != s)
|
||||
continue;
|
||||
|
||||
t->count--;
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
t->neighbour[0] = t->neighbour[1];
|
||||
fallthrough;
|
||||
case 1:
|
||||
t->neighbour[1] = t->neighbour[2];
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
memmove(&t->neighbour[i], &t->neighbour[i + 1],
|
||||
sizeof(t->neighbour[0]) *
|
||||
(t->count - i));
|
||||
}
|
||||
|
||||
if (t->count <= 0)
|
||||
|
|
|
@ -780,15 +780,12 @@ static u32 qdisc_alloc_handle(struct net_device *dev)
|
|||
|
||||
void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len)
|
||||
{
|
||||
bool qdisc_is_offloaded = sch->flags & TCQ_F_OFFLOADED;
|
||||
const struct Qdisc_class_ops *cops;
|
||||
unsigned long cl;
|
||||
u32 parentid;
|
||||
bool notify;
|
||||
int drops;
|
||||
|
||||
if (n == 0 && len == 0)
|
||||
return;
|
||||
drops = max_t(int, n, 0);
|
||||
rcu_read_lock();
|
||||
while ((parentid = sch->parent)) {
|
||||
|
@ -797,17 +794,8 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len)
|
|||
|
||||
if (sch->flags & TCQ_F_NOPARENT)
|
||||
break;
|
||||
/* Notify parent qdisc only if child qdisc becomes empty.
|
||||
*
|
||||
* If child was empty even before update then backlog
|
||||
* counter is screwed and we skip notification because
|
||||
* parent class is already passive.
|
||||
*
|
||||
* If the original child was offloaded then it is allowed
|
||||
* to be seem as empty, so the parent is notified anyway.
|
||||
*/
|
||||
notify = !sch->q.qlen && !WARN_ON_ONCE(!n &&
|
||||
!qdisc_is_offloaded);
|
||||
/* Notify parent qdisc only if child qdisc becomes empty. */
|
||||
notify = !sch->q.qlen;
|
||||
/* TODO: perform the search on a per txq basis */
|
||||
sch = qdisc_lookup_rcu(qdisc_dev(sch), TC_H_MAJ(parentid));
|
||||
if (sch == NULL) {
|
||||
|
@ -816,6 +804,9 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len)
|
|||
}
|
||||
cops = sch->ops->cl_ops;
|
||||
if (notify && cops->qlen_notify) {
|
||||
/* Note that qlen_notify must be idempotent as it may get called
|
||||
* multiple times.
|
||||
*/
|
||||
cl = cops->find(sch, parentid);
|
||||
cops->qlen_notify(sch, cl);
|
||||
}
|
||||
|
|
|
@ -119,6 +119,8 @@ vmci_transport_packet_init(struct vmci_transport_packet *pkt,
|
|||
u16 proto,
|
||||
struct vmci_handle handle)
|
||||
{
|
||||
memset(pkt, 0, sizeof(*pkt));
|
||||
|
||||
/* We register the stream control handler as an any cid handle so we
|
||||
* must always send from a source address of VMADDR_CID_ANY
|
||||
*/
|
||||
|
@ -131,8 +133,6 @@ vmci_transport_packet_init(struct vmci_transport_packet *pkt,
|
|||
pkt->type = type;
|
||||
pkt->src_port = src->svm_port;
|
||||
pkt->dst_port = dst->svm_port;
|
||||
memset(&pkt->proto, 0, sizeof(pkt->proto));
|
||||
memset(&pkt->_reserved2, 0, sizeof(pkt->_reserved2));
|
||||
|
||||
switch (pkt->type) {
|
||||
case VMCI_TRANSPORT_PACKET_TYPE_INVALID:
|
||||
|
|
Loading…
Add table
Reference in a new issue