mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-14 07:44:21 +08:00
Including fixes from WiFi, bluetooth and netfilter.
No known new regressions outstanding. Current release - regressions: - wifi: mt76: do not increase mcu skb refcount if retry is not supported Current release - new code bugs: - wifi: - rtw88: fix the RX aggregation in USB 3 mode - mac80211: fix memory corruption bug in struct ieee80211_chanctx Previous releases - regressions: - sched: - stop qdisc_tree_reduce_backlog on TC_H_ROOT - sch_api: fix xa_insert() error path in tcf_block_get_ext() - wifi: - revert "wifi: iwlwifi: remove retry loops in start" - cfg80211: clear wdev->cqm_config pointer on free - netfilter: fix potential crash in nf_send_reset6() - ip_tunnel: fix suspicious RCU usage warning in ip_tunnel_find() - bluetooth: fix null-ptr-deref in hci_read_supported_codecs - eth: mlxsw: add missing verification before pushing Tx header - eth: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds issue Previous releases - always broken: - wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower - netfilter: sanitize offset and length before calling skb_checksum() - core: - fix crash when config small gso_max_size/gso_ipv4_max_size - skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension - mptcp: protect sched with rcu_read_lock - eth: ice: fix crash on probe for DPLL enabled E810 LOM - eth: macsec: fix use-after-free while sending the offloading packet - eth: stmmac: fix unbalanced DMA map/unmap for non-paged SKB data - eth: hns3: fix kernel crash when 1588 is sent on HIP08 devices - eth: mtk_wed: fix path of MT7988 WO firmware Signed-off-by: Paolo Abeni <pabeni@redhat.com> -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmcjfLUSHHBhYmVuaUBy ZWRoYXQuY29tAAoJECkkeY3MjxOkONUP/35Vf0++xmZC12pvpL88B5RDqh9vH4Tv mYMIBUJNzXQhPoC27gGdY2v4U2ntVfbhFXVyYDJAVl5gwaCZkYufffrsBPqKBFBA tQnNpy+A2F+h4rRcTmugYoDdocwCK3qaAjZnF69SJ//6dtahorhOitdMoYbM2Vpj nNDWVPiN4pdIUBa+HrDeZ7f+Hou/i5q+mwXTh3/FZrJTWDdMfrFTSM3MMvKv+Fwk VoV7QwrR1APVjzgJmYujnil84d4D7etxHIgHFIvASJ5AgSZwnwVYWDfgTAalCD8a aoRtDvOZYJfVmRaitAFQd1tRrWn/Sk/QLqUyVfH8rZrGv3n/SEihZ00EtodOzAV4 31DSdpipdopfht5pFBN1o/VwvAWx2s34uXL1/L8eQWbMLOp4lQoqXoHbQ6yDac2p L6ESQH/DY3dMTsKgpkpUm7w4RzutoI3QXpoxlWO2KIwNcawiyVcdKKlKvfFgBQZr cGHG/Nzp6P6y9BiX36Rq3I7QKz/GjZN9zPe+3kPX99C2/UoO6St2yPBPLdh+BT2a 3cqq7ypkxvKtp5EByUjTRQwJZDsD8yY3VWTQN7GYAae0AWJlY8hET05tZEJmwWF8 TFKdme6lAN4XxNunEVQmUG93kuQRHJkPsN6pRhqGdOv/yUOxJT+meWBVJfMBQCq/ 70L0e6WiIJUe =3oi9 -----END PGP SIGNATURE----- Merge tag 'net-6.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Including fixes from WiFi, bluetooth and netfilter. No known new regressions outstanding. Current release - regressions: - wifi: mt76: do not increase mcu skb refcount if retry is not supported Current release - new code bugs: - wifi: - rtw88: fix the RX aggregation in USB 3 mode - mac80211: fix memory corruption bug in struct ieee80211_chanctx Previous releases - regressions: - sched: - stop qdisc_tree_reduce_backlog on TC_H_ROOT - sch_api: fix xa_insert() error path in tcf_block_get_ext() - wifi: - revert "wifi: iwlwifi: remove retry loops in start" - cfg80211: clear wdev->cqm_config pointer on free - netfilter: fix potential crash in nf_send_reset6() - ip_tunnel: fix suspicious RCU usage warning in ip_tunnel_find() - bluetooth: fix null-ptr-deref in hci_read_supported_codecs - eth: mlxsw: add missing verification before pushing Tx header - eth: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds issue Previous releases - always broken: - wifi: mac80211: do not pass a stopped vif to the driver in .get_txpower - netfilter: sanitize offset and length before calling skb_checksum() - core: - fix crash when config small gso_max_size/gso_ipv4_max_size - skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension - mptcp: protect sched with rcu_read_lock - eth: ice: fix crash on probe for DPLL enabled E810 LOM - eth: macsec: fix use-after-free while sending the offloading packet - eth: stmmac: fix unbalanced DMA map/unmap for non-paged SKB data - eth: hns3: fix kernel crash when 1588 is sent on HIP08 devices - eth: mtk_wed: fix path of MT7988 WO firmware" * tag 'net-6.12-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (70 commits) net: hns3: fix kernel crash when 1588 is sent on HIP08 devices net: hns3: fixed hclge_fetch_pf_reg accesses bar space out of bounds issue net: hns3: initialize reset_timer before hclgevf_misc_irq_init() net: hns3: don't auto enable misc vector net: hns3: Resolved the issue that the debugfs query result is inconsistent. net: hns3: fix missing features due to dev->features configuration too early net: hns3: fixed reset failure issues caused by the incorrect reset type net: hns3: add sync command to sync io-pgtable net: hns3: default enable tx bounce buffer when smmu enabled netfilter: nft_payload: sanitize offset and length before calling skb_checksum() net: ethernet: mtk_wed: fix path of MT7988 WO firmware selftests: forwarding: Add IPv6 GRE remote change tests mlxsw: spectrum_ipip: Fix memory leak when changing remote IPv6 address mlxsw: pci: Sync Rx buffers for device mlxsw: pci: Sync Rx buffers for CPU mlxsw: spectrum_ptp: Add missing verification before pushing Tx header net: skip offload for NETIF_F_IPV6_CSUM if ipv6 header contains extension Bluetooth: hci: fix null-ptr-deref in hci_read_supported_codecs netfilter: nf_reject_ipv6: fix potential crash in nf_send_reset6() netfilter: Fix use-after-free in get_info() ...
This commit is contained in:
commit
90602c251c
@ -16,7 +16,7 @@ ii) transmit network traffic, or any other that needs raw
|
||||
|
||||
Howto can be found at:
|
||||
|
||||
https://sites.google.com/site/packetmmap/
|
||||
https://web.archive.org/web/20220404160947/https://sites.google.com/site/packetmmap/
|
||||
|
||||
Please send your comments to
|
||||
- Ulisses Alonso Camaró <uaca@i.hate.spam.alumni.uv.es>
|
||||
@ -166,7 +166,8 @@ As capture, each frame contains two parts::
|
||||
/* bind socket to eth0 */
|
||||
bind(this->socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll));
|
||||
|
||||
A complete tutorial is available at: https://sites.google.com/site/packetmmap/
|
||||
A complete tutorial is available at:
|
||||
https://web.archive.org/web/20220404160947/https://sites.google.com/site/packetmmap/
|
||||
|
||||
By default, the user should put data at::
|
||||
|
||||
|
@ -1293,8 +1293,10 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer,
|
||||
|
||||
/* save the buffer addr until the last read operation */
|
||||
*save_buf = read_buf;
|
||||
}
|
||||
|
||||
/* get data ready for the first time to read */
|
||||
/* get data ready for the first time to read */
|
||||
if (!*ppos) {
|
||||
ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd,
|
||||
read_buf, hns3_dbg_cmd[index].buf_len);
|
||||
if (ret)
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/ipv6.h>
|
||||
#include <linux/iommu.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/pci.h>
|
||||
#include <linux/skbuff.h>
|
||||
@ -380,6 +381,24 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = {
|
||||
#define HNS3_INVALID_PTYPE \
|
||||
ARRAY_SIZE(hns3_rx_ptype_tbl)
|
||||
|
||||
static void hns3_dma_map_sync(struct device *dev, unsigned long iova)
|
||||
{
|
||||
struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
|
||||
struct iommu_iotlb_gather iotlb_gather;
|
||||
size_t granule;
|
||||
|
||||
if (!domain || !iommu_is_dma_domain(domain))
|
||||
return;
|
||||
|
||||
granule = 1 << __ffs(domain->pgsize_bitmap);
|
||||
iova = ALIGN_DOWN(iova, granule);
|
||||
iotlb_gather.start = iova;
|
||||
iotlb_gather.end = iova + granule - 1;
|
||||
iotlb_gather.pgsize = granule;
|
||||
|
||||
iommu_iotlb_sync(domain, &iotlb_gather);
|
||||
}
|
||||
|
||||
static irqreturn_t hns3_irq_handle(int irq, void *vector)
|
||||
{
|
||||
struct hns3_enet_tqp_vector *tqp_vector = vector;
|
||||
@ -1032,6 +1051,8 @@ static bool hns3_can_use_tx_sgl(struct hns3_enet_ring *ring,
|
||||
static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring)
|
||||
{
|
||||
u32 alloc_size = ring->tqp->handle->kinfo.tx_spare_buf_size;
|
||||
struct net_device *netdev = ring_to_netdev(ring);
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
struct hns3_tx_spare *tx_spare;
|
||||
struct page *page;
|
||||
dma_addr_t dma;
|
||||
@ -1073,6 +1094,7 @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring)
|
||||
tx_spare->buf = page_address(page);
|
||||
tx_spare->len = PAGE_SIZE << order;
|
||||
ring->tx_spare = tx_spare;
|
||||
ring->tx_copybreak = priv->tx_copybreak;
|
||||
return;
|
||||
|
||||
dma_mapping_error:
|
||||
@ -1724,7 +1746,9 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv,
|
||||
unsigned int type)
|
||||
{
|
||||
struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
|
||||
struct hnae3_handle *handle = ring->tqp->handle;
|
||||
struct device *dev = ring_to_dev(ring);
|
||||
struct hnae3_ae_dev *ae_dev;
|
||||
unsigned int size;
|
||||
dma_addr_t dma;
|
||||
|
||||
@ -1756,6 +1780,13 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Add a SYNC command to sync io-pgtale to avoid errors in pgtable
|
||||
* prefetch
|
||||
*/
|
||||
ae_dev = hns3_get_ae_dev(handle);
|
||||
if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3)
|
||||
hns3_dma_map_sync(dev, dma);
|
||||
|
||||
desc_cb->priv = priv;
|
||||
desc_cb->length = size;
|
||||
desc_cb->dma = dma;
|
||||
@ -2452,7 +2483,6 @@ static int hns3_nic_set_features(struct net_device *netdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
netdev->features = features;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -4868,6 +4898,30 @@ static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv)
|
||||
devm_kfree(&pdev->dev, priv->tqp_vector);
|
||||
}
|
||||
|
||||
static void hns3_update_tx_spare_buf_config(struct hns3_nic_priv *priv)
|
||||
{
|
||||
#define HNS3_MIN_SPARE_BUF_SIZE (2 * 1024 * 1024)
|
||||
#define HNS3_MAX_PACKET_SIZE (64 * 1024)
|
||||
|
||||
struct iommu_domain *domain = iommu_get_domain_for_dev(priv->dev);
|
||||
struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(priv->ae_handle);
|
||||
struct hnae3_handle *handle = priv->ae_handle;
|
||||
|
||||
if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3)
|
||||
return;
|
||||
|
||||
if (!(domain && iommu_is_dma_domain(domain)))
|
||||
return;
|
||||
|
||||
priv->min_tx_copybreak = HNS3_MAX_PACKET_SIZE;
|
||||
priv->min_tx_spare_buf_size = HNS3_MIN_SPARE_BUF_SIZE;
|
||||
|
||||
if (priv->tx_copybreak < priv->min_tx_copybreak)
|
||||
priv->tx_copybreak = priv->min_tx_copybreak;
|
||||
if (handle->kinfo.tx_spare_buf_size < priv->min_tx_spare_buf_size)
|
||||
handle->kinfo.tx_spare_buf_size = priv->min_tx_spare_buf_size;
|
||||
}
|
||||
|
||||
static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv,
|
||||
unsigned int ring_type)
|
||||
{
|
||||
@ -5101,6 +5155,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv)
|
||||
int i, j;
|
||||
int ret;
|
||||
|
||||
hns3_update_tx_spare_buf_config(priv);
|
||||
for (i = 0; i < ring_num; i++) {
|
||||
ret = hns3_alloc_ring_memory(&priv->ring[i]);
|
||||
if (ret) {
|
||||
@ -5305,6 +5360,8 @@ static int hns3_client_init(struct hnae3_handle *handle)
|
||||
priv->ae_handle = handle;
|
||||
priv->tx_timeout_count = 0;
|
||||
priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num;
|
||||
priv->min_tx_copybreak = 0;
|
||||
priv->min_tx_spare_buf_size = 0;
|
||||
set_bit(HNS3_NIC_STATE_DOWN, &priv->state);
|
||||
|
||||
handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL);
|
||||
|
@ -596,6 +596,8 @@ struct hns3_nic_priv {
|
||||
struct hns3_enet_coalesce rx_coal;
|
||||
u32 tx_copybreak;
|
||||
u32 rx_copybreak;
|
||||
u32 min_tx_copybreak;
|
||||
u32 min_tx_spare_buf_size;
|
||||
};
|
||||
|
||||
union l3_hdr_info {
|
||||
|
@ -1933,6 +1933,31 @@ static int hns3_set_tx_spare_buf_size(struct net_device *netdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hns3_check_tx_copybreak(struct net_device *netdev, u32 copybreak)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
|
||||
if (copybreak < priv->min_tx_copybreak) {
|
||||
netdev_err(netdev, "tx copybreak %u should be no less than %u!\n",
|
||||
copybreak, priv->min_tx_copybreak);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns3_check_tx_spare_buf_size(struct net_device *netdev, u32 buf_size)
|
||||
{
|
||||
struct hns3_nic_priv *priv = netdev_priv(netdev);
|
||||
|
||||
if (buf_size < priv->min_tx_spare_buf_size) {
|
||||
netdev_err(netdev,
|
||||
"tx spare buf size %u should be no less than %u!\n",
|
||||
buf_size, priv->min_tx_spare_buf_size);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hns3_set_tunable(struct net_device *netdev,
|
||||
const struct ethtool_tunable *tuna,
|
||||
const void *data)
|
||||
@ -1949,6 +1974,10 @@ static int hns3_set_tunable(struct net_device *netdev,
|
||||
|
||||
switch (tuna->id) {
|
||||
case ETHTOOL_TX_COPYBREAK:
|
||||
ret = hns3_check_tx_copybreak(netdev, *(u32 *)data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
priv->tx_copybreak = *(u32 *)data;
|
||||
|
||||
for (i = 0; i < h->kinfo.num_tqps; i++)
|
||||
@ -1963,6 +1992,10 @@ static int hns3_set_tunable(struct net_device *netdev,
|
||||
|
||||
break;
|
||||
case ETHTOOL_TX_COPYBREAK_BUF_SIZE:
|
||||
ret = hns3_check_tx_spare_buf_size(netdev, *(u32 *)data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size;
|
||||
new_tx_spare_buf_size = *(u32 *)data;
|
||||
netdev_info(netdev, "request to set tx spare buf size from %u to %u\n",
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/netdevice.h>
|
||||
@ -3584,6 +3585,17 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hclge_set_reset_pending(struct hclge_dev *hdev,
|
||||
enum hnae3_reset_type reset_type)
|
||||
{
|
||||
/* When an incorrect reset type is executed, the get_reset_level
|
||||
* function generates the HNAE3_NONE_RESET flag. As a result, this
|
||||
* type do not need to pending.
|
||||
*/
|
||||
if (reset_type != HNAE3_NONE_RESET)
|
||||
set_bit(reset_type, &hdev->reset_pending);
|
||||
}
|
||||
|
||||
static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
|
||||
{
|
||||
u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg;
|
||||
@ -3604,7 +3616,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
|
||||
*/
|
||||
if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) {
|
||||
dev_info(&hdev->pdev->dev, "IMP reset interrupt\n");
|
||||
set_bit(HNAE3_IMP_RESET, &hdev->reset_pending);
|
||||
hclge_set_reset_pending(hdev, HNAE3_IMP_RESET);
|
||||
set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
|
||||
*clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B);
|
||||
hdev->rst_stats.imp_rst_cnt++;
|
||||
@ -3614,7 +3626,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval)
|
||||
if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) {
|
||||
dev_info(&hdev->pdev->dev, "global reset interrupt\n");
|
||||
set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
|
||||
set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending);
|
||||
hclge_set_reset_pending(hdev, HNAE3_GLOBAL_RESET);
|
||||
*clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B);
|
||||
hdev->rst_stats.global_rst_cnt++;
|
||||
return HCLGE_VECTOR0_EVENT_RST;
|
||||
@ -3769,7 +3781,7 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev)
|
||||
snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s",
|
||||
HCLGE_NAME, pci_name(hdev->pdev));
|
||||
ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle,
|
||||
0, hdev->misc_vector.name, hdev);
|
||||
IRQ_NOAUTOEN, hdev->misc_vector.name, hdev);
|
||||
if (ret) {
|
||||
hclge_free_vector(hdev, 0);
|
||||
dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n",
|
||||
@ -4062,7 +4074,7 @@ static void hclge_do_reset(struct hclge_dev *hdev)
|
||||
case HNAE3_FUNC_RESET:
|
||||
dev_info(&pdev->dev, "PF reset requested\n");
|
||||
/* schedule again to check later */
|
||||
set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending);
|
||||
hclge_set_reset_pending(hdev, HNAE3_FUNC_RESET);
|
||||
hclge_reset_task_schedule(hdev);
|
||||
break;
|
||||
default:
|
||||
@ -4096,6 +4108,8 @@ static enum hnae3_reset_type hclge_get_reset_level(struct hnae3_ae_dev *ae_dev,
|
||||
clear_bit(HNAE3_FLR_RESET, addr);
|
||||
}
|
||||
|
||||
clear_bit(HNAE3_NONE_RESET, addr);
|
||||
|
||||
if (hdev->reset_type != HNAE3_NONE_RESET &&
|
||||
rst_level < hdev->reset_type)
|
||||
return HNAE3_NONE_RESET;
|
||||
@ -4237,7 +4251,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev)
|
||||
return false;
|
||||
} else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) {
|
||||
hdev->rst_stats.reset_fail_cnt++;
|
||||
set_bit(hdev->reset_type, &hdev->reset_pending);
|
||||
hclge_set_reset_pending(hdev, hdev->reset_type);
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"re-schedule reset task(%u)\n",
|
||||
hdev->rst_stats.reset_fail_cnt);
|
||||
@ -4480,8 +4494,20 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle)
|
||||
static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
|
||||
enum hnae3_reset_type rst_type)
|
||||
{
|
||||
#define HCLGE_SUPPORT_RESET_TYPE \
|
||||
(BIT(HNAE3_FLR_RESET) | BIT(HNAE3_FUNC_RESET) | \
|
||||
BIT(HNAE3_GLOBAL_RESET) | BIT(HNAE3_IMP_RESET))
|
||||
|
||||
struct hclge_dev *hdev = ae_dev->priv;
|
||||
|
||||
if (!(BIT(rst_type) & HCLGE_SUPPORT_RESET_TYPE)) {
|
||||
/* To prevent reset triggered by hclge_reset_event */
|
||||
set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
|
||||
dev_warn(&hdev->pdev->dev, "unsupported reset type %d\n",
|
||||
rst_type);
|
||||
return;
|
||||
}
|
||||
|
||||
set_bit(rst_type, &hdev->default_reset_request);
|
||||
}
|
||||
|
||||
@ -11891,9 +11917,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
||||
|
||||
hclge_init_rxd_adv_layout(hdev);
|
||||
|
||||
/* Enable MISC vector(vector0) */
|
||||
hclge_enable_vector(&hdev->misc_vector, true);
|
||||
|
||||
ret = hclge_init_wol(hdev);
|
||||
if (ret)
|
||||
dev_warn(&pdev->dev,
|
||||
@ -11906,6 +11929,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev)
|
||||
hclge_state_init(hdev);
|
||||
hdev->last_reset_time = jiffies;
|
||||
|
||||
/* Enable MISC vector(vector0) */
|
||||
enable_irq(hdev->misc_vector.vector_irq);
|
||||
hclge_enable_vector(&hdev->misc_vector, true);
|
||||
|
||||
dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n",
|
||||
HCLGE_DRIVER_NAME);
|
||||
|
||||
@ -12311,7 +12338,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev)
|
||||
|
||||
/* Disable MISC vector(vector0) */
|
||||
hclge_enable_vector(&hdev->misc_vector, false);
|
||||
synchronize_irq(hdev->misc_vector.vector_irq);
|
||||
disable_irq(hdev->misc_vector.vector_irq);
|
||||
|
||||
/* Disable all hw interrupts */
|
||||
hclge_config_mac_tnl_int(hdev, false);
|
||||
|
@ -58,6 +58,9 @@ bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb)
|
||||
struct hclge_dev *hdev = vport->back;
|
||||
struct hclge_ptp *ptp = hdev->ptp;
|
||||
|
||||
if (!ptp)
|
||||
return false;
|
||||
|
||||
if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) ||
|
||||
test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) {
|
||||
ptp->tx_skipped++;
|
||||
|
@ -510,9 +510,9 @@ out:
|
||||
static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
|
||||
struct hnae3_knic_private_info *kinfo)
|
||||
{
|
||||
#define HCLGE_RING_REG_OFFSET 0x200
|
||||
#define HCLGE_RING_INT_REG_OFFSET 0x4
|
||||
|
||||
struct hnae3_queue *tqp;
|
||||
int i, j, reg_num;
|
||||
int data_num_sum;
|
||||
u32 *reg = data;
|
||||
@ -533,10 +533,11 @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data,
|
||||
reg_num = ARRAY_SIZE(ring_reg_addr_list);
|
||||
for (j = 0; j < kinfo->num_tqps; j++) {
|
||||
reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg);
|
||||
tqp = kinfo->tqp[j];
|
||||
for (i = 0; i < reg_num; i++)
|
||||
*reg++ = hclge_read_dev(&hdev->hw,
|
||||
ring_reg_addr_list[i] +
|
||||
HCLGE_RING_REG_OFFSET * j);
|
||||
*reg++ = readl_relaxed(tqp->io_base -
|
||||
HCLGE_TQP_REG_OFFSET +
|
||||
ring_reg_addr_list[i]);
|
||||
}
|
||||
data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps;
|
||||
|
||||
|
@ -1395,6 +1395,17 @@ static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void hclgevf_set_reset_pending(struct hclgevf_dev *hdev,
|
||||
enum hnae3_reset_type reset_type)
|
||||
{
|
||||
/* When an incorrect reset type is executed, the get_reset_level
|
||||
* function generates the HNAE3_NONE_RESET flag. As a result, this
|
||||
* type do not need to pending.
|
||||
*/
|
||||
if (reset_type != HNAE3_NONE_RESET)
|
||||
set_bit(reset_type, &hdev->reset_pending);
|
||||
}
|
||||
|
||||
static int hclgevf_reset_wait(struct hclgevf_dev *hdev)
|
||||
{
|
||||
#define HCLGEVF_RESET_WAIT_US 20000
|
||||
@ -1544,7 +1555,7 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev)
|
||||
hdev->rst_stats.rst_fail_cnt);
|
||||
|
||||
if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT)
|
||||
set_bit(hdev->reset_type, &hdev->reset_pending);
|
||||
hclgevf_set_reset_pending(hdev, hdev->reset_type);
|
||||
|
||||
if (hclgevf_is_reset_pending(hdev)) {
|
||||
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
|
||||
@ -1664,6 +1675,8 @@ static enum hnae3_reset_type hclgevf_get_reset_level(unsigned long *addr)
|
||||
clear_bit(HNAE3_FLR_RESET, addr);
|
||||
}
|
||||
|
||||
clear_bit(HNAE3_NONE_RESET, addr);
|
||||
|
||||
return rst_level;
|
||||
}
|
||||
|
||||
@ -1673,14 +1686,15 @@ static void hclgevf_reset_event(struct pci_dev *pdev,
|
||||
struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev);
|
||||
struct hclgevf_dev *hdev = ae_dev->priv;
|
||||
|
||||
dev_info(&hdev->pdev->dev, "received reset request from VF enet\n");
|
||||
|
||||
if (hdev->default_reset_request)
|
||||
hdev->reset_level =
|
||||
hclgevf_get_reset_level(&hdev->default_reset_request);
|
||||
else
|
||||
hdev->reset_level = HNAE3_VF_FUNC_RESET;
|
||||
|
||||
dev_info(&hdev->pdev->dev, "received reset request from VF enet, reset level is %d\n",
|
||||
hdev->reset_level);
|
||||
|
||||
/* reset of this VF requested */
|
||||
set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state);
|
||||
hclgevf_reset_task_schedule(hdev);
|
||||
@ -1691,8 +1705,20 @@ static void hclgevf_reset_event(struct pci_dev *pdev,
|
||||
static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev,
|
||||
enum hnae3_reset_type rst_type)
|
||||
{
|
||||
#define HCLGEVF_SUPPORT_RESET_TYPE \
|
||||
(BIT(HNAE3_VF_RESET) | BIT(HNAE3_VF_FUNC_RESET) | \
|
||||
BIT(HNAE3_VF_PF_FUNC_RESET) | BIT(HNAE3_VF_FULL_RESET) | \
|
||||
BIT(HNAE3_FLR_RESET) | BIT(HNAE3_VF_EXP_RESET))
|
||||
|
||||
struct hclgevf_dev *hdev = ae_dev->priv;
|
||||
|
||||
if (!(BIT(rst_type) & HCLGEVF_SUPPORT_RESET_TYPE)) {
|
||||
/* To prevent reset triggered by hclge_reset_event */
|
||||
set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request);
|
||||
dev_info(&hdev->pdev->dev, "unsupported reset type %d\n",
|
||||
rst_type);
|
||||
return;
|
||||
}
|
||||
set_bit(rst_type, &hdev->default_reset_request);
|
||||
}
|
||||
|
||||
@ -1849,14 +1875,14 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev)
|
||||
*/
|
||||
if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) {
|
||||
/* prepare for full reset of stack + pcie interface */
|
||||
set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending);
|
||||
hclgevf_set_reset_pending(hdev, HNAE3_VF_FULL_RESET);
|
||||
|
||||
/* "defer" schedule the reset task again */
|
||||
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
|
||||
} else {
|
||||
hdev->reset_attempts++;
|
||||
|
||||
set_bit(hdev->reset_level, &hdev->reset_pending);
|
||||
hclgevf_set_reset_pending(hdev, hdev->reset_level);
|
||||
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
|
||||
}
|
||||
hclgevf_reset_task_schedule(hdev);
|
||||
@ -1979,7 +2005,7 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev,
|
||||
rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING);
|
||||
dev_info(&hdev->pdev->dev,
|
||||
"receive reset interrupt 0x%x!\n", rst_ing_reg);
|
||||
set_bit(HNAE3_VF_RESET, &hdev->reset_pending);
|
||||
hclgevf_set_reset_pending(hdev, HNAE3_VF_RESET);
|
||||
set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state);
|
||||
set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state);
|
||||
*clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B);
|
||||
@ -2289,6 +2315,7 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev)
|
||||
clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state);
|
||||
|
||||
INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task);
|
||||
timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
|
||||
|
||||
mutex_init(&hdev->mbx_resp.mbx_mutex);
|
||||
sema_init(&hdev->reset_sem, 1);
|
||||
@ -2988,7 +3015,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev)
|
||||
HCLGEVF_DRIVER_NAME);
|
||||
|
||||
hclgevf_task_schedule(hdev, round_jiffies_relative(HZ));
|
||||
timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0);
|
||||
|
||||
return 0;
|
||||
|
||||
|
@ -123,10 +123,10 @@ int hclgevf_get_regs_len(struct hnae3_handle *handle)
|
||||
void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
|
||||
void *data)
|
||||
{
|
||||
#define HCLGEVF_RING_REG_OFFSET 0x200
|
||||
#define HCLGEVF_RING_INT_REG_OFFSET 0x4
|
||||
|
||||
struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
|
||||
struct hnae3_queue *tqp;
|
||||
int i, j, reg_um;
|
||||
u32 *reg = data;
|
||||
|
||||
@ -147,10 +147,11 @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version,
|
||||
reg_um = ARRAY_SIZE(ring_reg_addr_list);
|
||||
for (j = 0; j < hdev->num_tqps; j++) {
|
||||
reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg);
|
||||
tqp = &hdev->htqp[j].q;
|
||||
for (i = 0; i < reg_um; i++)
|
||||
*reg++ = hclgevf_read_dev(&hdev->hw,
|
||||
ring_reg_addr_list[i] +
|
||||
HCLGEVF_RING_REG_OFFSET * j);
|
||||
*reg++ = readl_relaxed(tqp->io_base -
|
||||
HCLGEVF_TQP_REG_OFFSET +
|
||||
ring_reg_addr_list[i]);
|
||||
}
|
||||
|
||||
reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list);
|
||||
|
@ -989,5 +989,11 @@ ice_devlink_port_new(struct devlink *devlink,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (!ice_is_eswitch_mode_switchdev(pf)) {
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"SF ports are only supported in eswitch switchdev mode");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return ice_alloc_dynamic_port(pf, new_attr, extack, devlink_port);
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#define ICE_DPLL_PIN_IDX_INVALID 0xff
|
||||
#define ICE_DPLL_RCLK_NUM_PER_PF 1
|
||||
#define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25
|
||||
#define ICE_DPLL_PIN_GEN_RCLK_FREQ 1953125
|
||||
|
||||
/**
|
||||
* enum ice_dpll_pin_type - enumerate ice pin types:
|
||||
@ -2063,6 +2064,73 @@ static int ice_dpll_init_worker(struct ice_pf *pf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_dpll_init_info_pins_generic - initializes generic pins info
|
||||
* @pf: board private structure
|
||||
* @input: if input pins initialized
|
||||
*
|
||||
* Init information for generic pins, cache them in PF's pins structures.
|
||||
*
|
||||
* Return:
|
||||
* * 0 - success
|
||||
* * negative - init failure reason
|
||||
*/
|
||||
static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input)
|
||||
{
|
||||
struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps;
|
||||
static const char labels[][sizeof("99")] = {
|
||||
"0", "1", "2", "3", "4", "5", "6", "7", "8",
|
||||
"9", "10", "11", "12", "13", "14", "15" };
|
||||
u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE;
|
||||
enum ice_dpll_pin_type pin_type;
|
||||
int i, pin_num, ret = -EINVAL;
|
||||
struct ice_dpll_pin *pins;
|
||||
u32 phase_adj_max;
|
||||
|
||||
if (input) {
|
||||
pin_num = pf->dplls.num_inputs;
|
||||
pins = pf->dplls.inputs;
|
||||
phase_adj_max = pf->dplls.input_phase_adj_max;
|
||||
pin_type = ICE_DPLL_PIN_TYPE_INPUT;
|
||||
cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE;
|
||||
} else {
|
||||
pin_num = pf->dplls.num_outputs;
|
||||
pins = pf->dplls.outputs;
|
||||
phase_adj_max = pf->dplls.output_phase_adj_max;
|
||||
pin_type = ICE_DPLL_PIN_TYPE_OUTPUT;
|
||||
}
|
||||
if (pin_num > ARRAY_SIZE(labels))
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < pin_num; i++) {
|
||||
pins[i].idx = i;
|
||||
pins[i].prop.board_label = labels[i];
|
||||
pins[i].prop.phase_range.min = phase_adj_max;
|
||||
pins[i].prop.phase_range.max = -phase_adj_max;
|
||||
pins[i].prop.capabilities = cap;
|
||||
pins[i].pf = pf;
|
||||
ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL);
|
||||
if (ret)
|
||||
break;
|
||||
if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ)
|
||||
pins[i].prop.type = DPLL_PIN_TYPE_MUX;
|
||||
else
|
||||
pins[i].prop.type = DPLL_PIN_TYPE_EXT;
|
||||
if (!input)
|
||||
continue;
|
||||
ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i,
|
||||
&de->input_prio[i]);
|
||||
if (ret)
|
||||
break;
|
||||
ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i,
|
||||
&dp->input_prio[i]);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_dpll_init_info_direct_pins - initializes direct pins info
|
||||
* @pf: board private structure
|
||||
@ -2101,6 +2169,8 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
if (num_pins != ice_cgu_get_num_pins(hw, input))
|
||||
return ice_dpll_init_info_pins_generic(pf, input);
|
||||
|
||||
for (i = 0; i < num_pins; i++) {
|
||||
caps = 0;
|
||||
|
@ -34,7 +34,6 @@ static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_inputs[] = {
|
||||
ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common },
|
||||
{ "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS,
|
||||
ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz },
|
||||
{ "OCXO", ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, 0, },
|
||||
};
|
||||
|
||||
static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = {
|
||||
@ -52,7 +51,6 @@ static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = {
|
||||
ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common },
|
||||
{ "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS,
|
||||
ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz },
|
||||
{ "OCXO", ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, },
|
||||
};
|
||||
|
||||
static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_outputs[] = {
|
||||
@ -5964,6 +5962,25 @@ ice_cgu_get_pin_desc(struct ice_hw *hw, bool input, int *size)
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_cgu_get_num_pins - get pin description array size
|
||||
* @hw: pointer to the hw struct
|
||||
* @input: if request is done against input or output pins
|
||||
*
|
||||
* Return: size of pin description array for given hw.
|
||||
*/
|
||||
int ice_cgu_get_num_pins(struct ice_hw *hw, bool input)
|
||||
{
|
||||
const struct ice_cgu_pin_desc *t;
|
||||
int size;
|
||||
|
||||
t = ice_cgu_get_pin_desc(hw, input, &size);
|
||||
if (t)
|
||||
return size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ice_cgu_get_pin_type - get pin's type
|
||||
* @hw: pointer to the hw struct
|
||||
|
@ -404,6 +404,7 @@ int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data);
|
||||
int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data);
|
||||
int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data);
|
||||
bool ice_is_pca9575_present(struct ice_hw *hw);
|
||||
int ice_cgu_get_num_pins(struct ice_hw *hw, bool input);
|
||||
enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input);
|
||||
struct dpll_pin_frequency *
|
||||
ice_cgu_get_pin_freq_supp(struct ice_hw *hw, u8 pin, bool input, u8 *num);
|
||||
|
@ -907,7 +907,7 @@ static int igb_request_msix(struct igb_adapter *adapter)
|
||||
int i, err = 0, vector = 0, free_vector = 0;
|
||||
|
||||
err = request_irq(adapter->msix_entries[vector].vector,
|
||||
igb_msix_other, 0, netdev->name, adapter);
|
||||
igb_msix_other, IRQF_NO_THREAD, netdev->name, adapter);
|
||||
if (err)
|
||||
goto err_out;
|
||||
|
||||
|
@ -91,8 +91,8 @@ enum mtk_wed_dummy_cr_idx {
|
||||
#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
|
||||
#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
|
||||
#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
|
||||
#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin"
|
||||
#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin"
|
||||
#define MT7988_FIRMWARE_WO0 "mediatek/mt7988/mt7988_wo_0.bin"
|
||||
#define MT7988_FIRMWARE_WO1 "mediatek/mt7988/mt7988_wo_1.bin"
|
||||
|
||||
#define MTK_WO_MCU_CFG_LS_BASE 0
|
||||
#define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000)
|
||||
|
@ -389,15 +389,27 @@ static void mlxsw_pci_wqe_frag_unmap(struct mlxsw_pci *mlxsw_pci, char *wqe,
|
||||
dma_unmap_single(&pdev->dev, mapaddr, frag_len, direction);
|
||||
}
|
||||
|
||||
static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
|
||||
static struct sk_buff *mlxsw_pci_rdq_build_skb(struct mlxsw_pci_queue *q,
|
||||
struct page *pages[],
|
||||
u16 byte_count)
|
||||
{
|
||||
struct mlxsw_pci_queue *cq = q->u.rdq.cq;
|
||||
unsigned int linear_data_size;
|
||||
struct page_pool *page_pool;
|
||||
struct sk_buff *skb;
|
||||
int page_index = 0;
|
||||
bool linear_only;
|
||||
void *data;
|
||||
|
||||
linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE;
|
||||
linear_data_size = linear_only ? byte_count :
|
||||
PAGE_SIZE -
|
||||
MLXSW_PCI_RX_BUF_SW_OVERHEAD;
|
||||
|
||||
page_pool = cq->u.cq.page_pool;
|
||||
page_pool_dma_sync_for_cpu(page_pool, pages[page_index],
|
||||
MLXSW_PCI_SKB_HEADROOM, linear_data_size);
|
||||
|
||||
data = page_address(pages[page_index]);
|
||||
net_prefetch(data);
|
||||
|
||||
@ -405,11 +417,6 @@ static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
|
||||
if (unlikely(!skb))
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE;
|
||||
linear_data_size = linear_only ? byte_count :
|
||||
PAGE_SIZE -
|
||||
MLXSW_PCI_RX_BUF_SW_OVERHEAD;
|
||||
|
||||
skb_reserve(skb, MLXSW_PCI_SKB_HEADROOM);
|
||||
skb_put(skb, linear_data_size);
|
||||
|
||||
@ -425,6 +432,7 @@ static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[],
|
||||
|
||||
page = pages[page_index];
|
||||
frag_size = min(byte_count, PAGE_SIZE);
|
||||
page_pool_dma_sync_for_cpu(page_pool, page, 0, frag_size);
|
||||
skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags,
|
||||
page, 0, frag_size, PAGE_SIZE);
|
||||
byte_count -= frag_size;
|
||||
@ -760,7 +768,7 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
skb = mlxsw_pci_rdq_build_skb(pages, byte_count);
|
||||
skb = mlxsw_pci_rdq_build_skb(q, pages, byte_count);
|
||||
if (IS_ERR(skb)) {
|
||||
dev_err_ratelimited(&pdev->dev, "Failed to build skb for RDQ\n");
|
||||
mlxsw_pci_rdq_pages_recycle(q, pages, num_sg_entries);
|
||||
@ -988,12 +996,13 @@ static int mlxsw_pci_cq_page_pool_init(struct mlxsw_pci_queue *q,
|
||||
if (cq_type != MLXSW_PCI_CQ_RDQ)
|
||||
return 0;
|
||||
|
||||
pp_params.flags = PP_FLAG_DMA_MAP;
|
||||
pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV;
|
||||
pp_params.pool_size = MLXSW_PCI_WQE_COUNT * mlxsw_pci->num_sg_entries;
|
||||
pp_params.nid = dev_to_node(&mlxsw_pci->pdev->dev);
|
||||
pp_params.dev = &mlxsw_pci->pdev->dev;
|
||||
pp_params.napi = &q->u.cq.napi;
|
||||
pp_params.dma_dir = DMA_FROM_DEVICE;
|
||||
pp_params.max_len = PAGE_SIZE;
|
||||
|
||||
page_pool = page_pool_create(&pp_params);
|
||||
if (IS_ERR(page_pool))
|
||||
|
@ -481,11 +481,33 @@ mlxsw_sp_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp,
|
||||
struct mlxsw_sp_ipip_entry *ipip_entry,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
u32 new_kvdl_index, old_kvdl_index = ipip_entry->dip_kvdl_index;
|
||||
struct in6_addr old_addr6 = ipip_entry->parms.daddr.addr6;
|
||||
struct mlxsw_sp_ipip_parms new_parms;
|
||||
int err;
|
||||
|
||||
new_parms = mlxsw_sp_ipip_netdev_parms_init_gre6(ipip_entry->ol_dev);
|
||||
return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
|
||||
&new_parms, extack);
|
||||
|
||||
err = mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp,
|
||||
&new_parms.daddr.addr6,
|
||||
&new_kvdl_index);
|
||||
if (err)
|
||||
return err;
|
||||
ipip_entry->dip_kvdl_index = new_kvdl_index;
|
||||
|
||||
err = mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry,
|
||||
&new_parms, extack);
|
||||
if (err)
|
||||
goto err_change_gre;
|
||||
|
||||
mlxsw_sp_ipv6_addr_put(mlxsw_sp, &old_addr6);
|
||||
|
||||
return 0;
|
||||
|
||||
err_change_gre:
|
||||
ipip_entry->dip_kvdl_index = old_kvdl_index;
|
||||
mlxsw_sp_ipv6_addr_put(mlxsw_sp, &new_parms.daddr.addr6);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "spectrum.h"
|
||||
#include "spectrum_ptp.h"
|
||||
#include "core.h"
|
||||
#include "txheader.h"
|
||||
|
||||
#define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT 29
|
||||
#define MLXSW_SP1_PTP_CLOCK_FREQ_KHZ 156257 /* 6.4nSec */
|
||||
@ -1684,6 +1685,12 @@ int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core,
|
||||
struct sk_buff *skb,
|
||||
const struct mlxsw_tx_info *tx_info)
|
||||
{
|
||||
if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) {
|
||||
this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped);
|
||||
dev_kfree_skb_any(skb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mlxsw_sp_txhdr_construct(skb, tx_info);
|
||||
return 0;
|
||||
}
|
||||
|
@ -203,8 +203,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv,
|
||||
readl(ioaddr + DMA_CHAN_TX_CONTROL(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_RX_CONTROL(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_RX_CONTROL(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_TX_BASE_ADDR_HI(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_TX_BASE_ADDR_HI(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_TX_BASE_ADDR(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_RX_BASE_ADDR_HI(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_RX_BASE_ADDR_HI(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_RX_BASE_ADDR(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_TX_END_ADDR(default_addrs, channel) / 4] =
|
||||
@ -225,8 +229,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv,
|
||||
readl(ioaddr + DMA_CHAN_CUR_TX_DESC(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_CUR_RX_DESC(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_CUR_RX_DESC(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_CUR_TX_BUF_ADDR_HI(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR_HI(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_CUR_RX_BUF_ADDR_HI(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR_HI(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(default_addrs, channel) / 4] =
|
||||
readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(dwmac4_addrs, channel));
|
||||
reg_space[DMA_CHAN_STATUS(default_addrs, channel) / 4] =
|
||||
|
@ -127,7 +127,9 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs,
|
||||
#define DMA_CHAN_SLOT_CTRL_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x3c)
|
||||
#define DMA_CHAN_CUR_TX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x44)
|
||||
#define DMA_CHAN_CUR_RX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x4c)
|
||||
#define DMA_CHAN_CUR_TX_BUF_ADDR_HI(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x50)
|
||||
#define DMA_CHAN_CUR_TX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x54)
|
||||
#define DMA_CHAN_CUR_RX_BUF_ADDR_HI(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x58)
|
||||
#define DMA_CHAN_CUR_RX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x5c)
|
||||
#define DMA_CHAN_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x60)
|
||||
|
||||
|
@ -4304,11 +4304,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
if (dma_mapping_error(priv->device, des))
|
||||
goto dma_map_err;
|
||||
|
||||
tx_q->tx_skbuff_dma[first_entry].buf = des;
|
||||
tx_q->tx_skbuff_dma[first_entry].len = skb_headlen(skb);
|
||||
tx_q->tx_skbuff_dma[first_entry].map_as_page = false;
|
||||
tx_q->tx_skbuff_dma[first_entry].buf_type = STMMAC_TXBUF_T_SKB;
|
||||
|
||||
if (priv->dma_cap.addr64 <= 32) {
|
||||
first->des0 = cpu_to_le32(des);
|
||||
|
||||
@ -4327,6 +4322,23 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
|
||||
stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue);
|
||||
|
||||
/* In case two or more DMA transmit descriptors are allocated for this
|
||||
* non-paged SKB data, the DMA buffer address should be saved to
|
||||
* tx_q->tx_skbuff_dma[].buf corresponding to the last descriptor,
|
||||
* and leave the other tx_q->tx_skbuff_dma[].buf as NULL to guarantee
|
||||
* that stmmac_tx_clean() does not unmap the entire DMA buffer too early
|
||||
* since the tail areas of the DMA buffer can be accessed by DMA engine
|
||||
* sooner or later.
|
||||
* By saving the DMA buffer address to tx_q->tx_skbuff_dma[].buf
|
||||
* corresponding to the last descriptor, stmmac_tx_clean() will unmap
|
||||
* this DMA buffer right after the DMA engine completely finishes the
|
||||
* full buffer transmission.
|
||||
*/
|
||||
tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des;
|
||||
tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb);
|
||||
tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false;
|
||||
tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB;
|
||||
|
||||
/* Prepare fragments */
|
||||
for (i = 0; i < nfrags; i++) {
|
||||
const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
|
||||
|
@ -1702,20 +1702,24 @@ static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[])
|
||||
return -EINVAL;
|
||||
|
||||
if (data[IFLA_GTP_FD0]) {
|
||||
u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
|
||||
int fd0 = nla_get_u32(data[IFLA_GTP_FD0]);
|
||||
|
||||
sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
|
||||
if (IS_ERR(sk0))
|
||||
return PTR_ERR(sk0);
|
||||
if (fd0 >= 0) {
|
||||
sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp);
|
||||
if (IS_ERR(sk0))
|
||||
return PTR_ERR(sk0);
|
||||
}
|
||||
}
|
||||
|
||||
if (data[IFLA_GTP_FD1]) {
|
||||
u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
|
||||
int fd1 = nla_get_u32(data[IFLA_GTP_FD1]);
|
||||
|
||||
sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
|
||||
if (IS_ERR(sk1u)) {
|
||||
gtp_encap_disable_sock(sk0);
|
||||
return PTR_ERR(sk1u);
|
||||
if (fd1 >= 0) {
|
||||
sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp);
|
||||
if (IS_ERR(sk1u)) {
|
||||
gtp_encap_disable_sock(sk0);
|
||||
return PTR_ERR(sk1u);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3798,8 +3798,7 @@ static void macsec_free_netdev(struct net_device *dev)
|
||||
{
|
||||
struct macsec_dev *macsec = macsec_priv(dev);
|
||||
|
||||
if (macsec->secy.tx_sc.md_dst)
|
||||
metadata_dst_free(macsec->secy.tx_sc.md_dst);
|
||||
dst_release(&macsec->secy.tx_sc.md_dst->dst);
|
||||
free_percpu(macsec->stats);
|
||||
free_percpu(macsec->secy.tx_sc.stats);
|
||||
|
||||
|
@ -588,6 +588,9 @@ static int mctp_i2c_header_create(struct sk_buff *skb, struct net_device *dev,
|
||||
if (len > MCTP_I2C_MAXMTU)
|
||||
return -EMSGSIZE;
|
||||
|
||||
if (!daddr || !saddr)
|
||||
return -EINVAL;
|
||||
|
||||
lldst = *((u8 *)daddr);
|
||||
llsrc = *((u8 *)saddr);
|
||||
|
||||
|
@ -1377,10 +1377,12 @@ static ssize_t nsim_nexthop_bucket_activity_write(struct file *file,
|
||||
|
||||
if (pos != 0)
|
||||
return -EINVAL;
|
||||
if (size > sizeof(buf))
|
||||
if (size > sizeof(buf) - 1)
|
||||
return -EINVAL;
|
||||
if (copy_from_user(buf, user_buf, size))
|
||||
return -EFAULT;
|
||||
buf[size] = 0;
|
||||
|
||||
if (sscanf(buf, "%u %hu", &nhid, &bucket_index) != 2)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -1076,6 +1076,7 @@ static const struct usb_device_id products[] = {
|
||||
USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7),
|
||||
.driver_info = (unsigned long)&qmi_wwan_info,
|
||||
},
|
||||
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)}, /* Quectel RG650V */
|
||||
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */
|
||||
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */
|
||||
{QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */
|
||||
|
@ -10069,6 +10069,7 @@ static const struct usb_device_id rtl8152_table[] = {
|
||||
{ USB_DEVICE(VENDOR_ID_LENOVO, 0x3062) },
|
||||
{ USB_DEVICE(VENDOR_ID_LENOVO, 0x3069) },
|
||||
{ USB_DEVICE(VENDOR_ID_LENOVO, 0x3082) },
|
||||
{ USB_DEVICE(VENDOR_ID_LENOVO, 0x3098) },
|
||||
{ USB_DEVICE(VENDOR_ID_LENOVO, 0x7205) },
|
||||
{ USB_DEVICE(VENDOR_ID_LENOVO, 0x720c) },
|
||||
{ USB_DEVICE(VENDOR_ID_LENOVO, 0x7214) },
|
||||
|
@ -3043,9 +3043,14 @@ ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar,
|
||||
struct sk_buff *msdu)
|
||||
{
|
||||
struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu);
|
||||
struct ath10k_mgmt_tx_pkt_addr *pkt_addr;
|
||||
struct ath10k_wmi *wmi = &ar->wmi;
|
||||
|
||||
idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
|
||||
spin_lock_bh(&ar->data_lock);
|
||||
pkt_addr = idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id);
|
||||
spin_unlock_bh(&ar->data_lock);
|
||||
|
||||
kfree(pkt_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2441,6 +2441,7 @@ wmi_process_mgmt_tx_comp(struct ath10k *ar, struct mgmt_tx_compl_params *param)
|
||||
dma_unmap_single(ar->dev, pkt_addr->paddr,
|
||||
msdu->len, DMA_TO_DEVICE);
|
||||
info = IEEE80211_SKB_CB(msdu);
|
||||
kfree(pkt_addr);
|
||||
|
||||
if (param->status) {
|
||||
info->flags &= ~IEEE80211_TX_STAT_ACK;
|
||||
@ -9612,6 +9613,7 @@ static int ath10k_wmi_mgmt_tx_clean_up_pending(int msdu_id, void *ptr,
|
||||
dma_unmap_single(ar->dev, pkt_addr->paddr,
|
||||
msdu->len, DMA_TO_DEVICE);
|
||||
ieee80211_free_txskb(ar->hw, msdu);
|
||||
kfree(pkt_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -5291,8 +5291,11 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id,
|
||||
hal_status == HAL_TLV_STATUS_PPDU_DONE) {
|
||||
rx_mon_stats->status_ppdu_done++;
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE;
|
||||
ath11k_dp_rx_mon_dest_process(ar, mac_id, budget, napi);
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
|
||||
if (!ab->hw_params.full_monitor_mode) {
|
||||
ath11k_dp_rx_mon_dest_process(ar, mac_id,
|
||||
budget, napi);
|
||||
pmon->mon_ppdu_status = DP_PPDU_STATUS_START;
|
||||
}
|
||||
}
|
||||
|
||||
if (ppdu_info->peer_id == HAL_INVALID_PEERID ||
|
||||
|
@ -306,7 +306,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
|
||||
struct sk_buff *skb)
|
||||
{
|
||||
struct wil6210_rtap {
|
||||
struct ieee80211_radiotap_header rthdr;
|
||||
struct ieee80211_radiotap_header_fixed rthdr;
|
||||
/* fields should be in the order of bits in rthdr.it_present */
|
||||
/* flags */
|
||||
u8 flags;
|
||||
|
@ -27,6 +27,7 @@ source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig"
|
||||
config BRCM_TRACING
|
||||
bool "Broadcom device tracing"
|
||||
depends on BRCMSMAC || BRCMFMAC
|
||||
depends on TRACING
|
||||
help
|
||||
If you say Y here, the Broadcom wireless drivers will register
|
||||
with ftrace to dump event information into the trace ringbuffer.
|
||||
|
@ -2518,7 +2518,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i,
|
||||
* to build this manually element by element, we can write it much
|
||||
* more efficiently than we can parse it. ORDER MATTERS HERE */
|
||||
struct ipw_rt_hdr {
|
||||
struct ieee80211_radiotap_header rt_hdr;
|
||||
struct ieee80211_radiotap_header_fixed rt_hdr;
|
||||
s8 rt_dbmsignal; /* signal in dbM, kluged to signed */
|
||||
} *ipw_rt;
|
||||
|
||||
|
@ -1143,7 +1143,7 @@ struct ipw_prom_priv {
|
||||
* structure is provided regardless of any bits unset.
|
||||
*/
|
||||
struct ipw_rt_hdr {
|
||||
struct ieee80211_radiotap_header rt_hdr;
|
||||
struct ieee80211_radiotap_header_fixed rt_hdr;
|
||||
u64 rt_tsf; /* TSF */ /* XXX */
|
||||
u8 rt_flags; /* radiotap packet flags */
|
||||
u8 rt_rate; /* rate in 500kb/s */
|
||||
|
@ -3122,6 +3122,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
|
||||
struct il_cmd_meta *out_meta;
|
||||
dma_addr_t phys_addr;
|
||||
unsigned long flags;
|
||||
u8 *out_payload;
|
||||
u32 idx;
|
||||
u16 fix_size;
|
||||
|
||||
@ -3157,6 +3158,16 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
|
||||
out_cmd = txq->cmd[idx];
|
||||
out_meta = &txq->meta[idx];
|
||||
|
||||
/* The payload is in the same place in regular and huge
|
||||
* command buffers, but we need to let the compiler know when
|
||||
* we're using a larger payload buffer to avoid "field-
|
||||
* spanning write" warnings at run-time for huge commands.
|
||||
*/
|
||||
if (cmd->flags & CMD_SIZE_HUGE)
|
||||
out_payload = ((struct il_device_cmd_huge *)out_cmd)->cmd.payload;
|
||||
else
|
||||
out_payload = out_cmd->cmd.payload;
|
||||
|
||||
if (WARN_ON(out_meta->flags & CMD_MAPPED)) {
|
||||
spin_unlock_irqrestore(&il->hcmd_lock, flags);
|
||||
return -ENOSPC;
|
||||
@ -3170,7 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd)
|
||||
out_meta->callback = cmd->callback;
|
||||
|
||||
out_cmd->hdr.cmd = cmd->id;
|
||||
memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len);
|
||||
memcpy(out_payload, cmd->data, cmd->len);
|
||||
|
||||
/* At this point, the out_cmd now has all of the incoming cmd
|
||||
* information */
|
||||
@ -4962,6 +4973,8 @@ il_pci_resume(struct device *device)
|
||||
*/
|
||||
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
|
||||
|
||||
_il_wr(il, CSR_INT, 0xffffffff);
|
||||
_il_wr(il, CSR_FH_INT_STATUS, 0xffffffff);
|
||||
il_enable_interrupts(il);
|
||||
|
||||
if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
|
||||
|
@ -560,6 +560,18 @@ struct il_device_cmd {
|
||||
|
||||
#define TFD_MAX_PAYLOAD_SIZE (sizeof(struct il_device_cmd))
|
||||
|
||||
/**
|
||||
* struct il_device_cmd_huge
|
||||
*
|
||||
* For use when sending huge commands.
|
||||
*/
|
||||
struct il_device_cmd_huge {
|
||||
struct il_cmd_header hdr; /* uCode API */
|
||||
union {
|
||||
u8 payload[IL_MAX_CMD_SIZE - sizeof(struct il_cmd_header)];
|
||||
} __packed cmd;
|
||||
} __packed;
|
||||
|
||||
struct il_host_cmd {
|
||||
const void *data;
|
||||
unsigned long reply_page;
|
||||
|
@ -429,38 +429,28 @@ out_free:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int iwl_acpi_sar_set_profile(union acpi_object *table,
|
||||
struct iwl_sar_profile *profile,
|
||||
bool enabled, u8 num_chains,
|
||||
u8 num_sub_bands)
|
||||
static int
|
||||
iwl_acpi_parse_chains_table(union acpi_object *table,
|
||||
struct iwl_sar_profile_chain *chains,
|
||||
u8 num_chains, u8 num_sub_bands)
|
||||
{
|
||||
int i, j, idx = 0;
|
||||
|
||||
/*
|
||||
* The table from ACPI is flat, but we store it in a
|
||||
* structured array.
|
||||
*/
|
||||
for (i = 0; i < BIOS_SAR_MAX_CHAINS_PER_PROFILE; i++) {
|
||||
for (j = 0; j < BIOS_SAR_MAX_SUB_BANDS_NUM; j++) {
|
||||
for (u8 chain = 0; chain < num_chains; chain++) {
|
||||
for (u8 subband = 0; subband < BIOS_SAR_MAX_SUB_BANDS_NUM;
|
||||
subband++) {
|
||||
/* if we don't have the values, use the default */
|
||||
if (i >= num_chains || j >= num_sub_bands) {
|
||||
profile->chains[i].subbands[j] = 0;
|
||||
if (subband >= num_sub_bands) {
|
||||
chains[chain].subbands[subband] = 0;
|
||||
} else if (table->type != ACPI_TYPE_INTEGER ||
|
||||
table->integer.value > U8_MAX) {
|
||||
return -EINVAL;
|
||||
} else {
|
||||
if (table[idx].type != ACPI_TYPE_INTEGER ||
|
||||
table[idx].integer.value > U8_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
profile->chains[i].subbands[j] =
|
||||
table[idx].integer.value;
|
||||
|
||||
idx++;
|
||||
chains[chain].subbands[subband] =
|
||||
table->integer.value;
|
||||
table++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Only if all values were valid can the profile be enabled */
|
||||
profile->enabled = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -543,9 +533,11 @@ read_table:
|
||||
/* The profile from WRDS is officially profile 1, but goes
|
||||
* into sar_profiles[0] (because we don't have a profile 0).
|
||||
*/
|
||||
ret = iwl_acpi_sar_set_profile(table, &fwrt->sar_profiles[0],
|
||||
flags & IWL_SAR_ENABLE_MSK,
|
||||
num_chains, num_sub_bands);
|
||||
ret = iwl_acpi_parse_chains_table(table, fwrt->sar_profiles[0].chains,
|
||||
num_chains, num_sub_bands);
|
||||
if (!ret && flags & IWL_SAR_ENABLE_MSK)
|
||||
fwrt->sar_profiles[0].enabled = true;
|
||||
|
||||
out_free:
|
||||
kfree(data);
|
||||
return ret;
|
||||
@ -557,7 +549,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
|
||||
bool enabled;
|
||||
int i, n_profiles, tbl_rev, pos;
|
||||
int ret = 0;
|
||||
u8 num_chains, num_sub_bands;
|
||||
u8 num_sub_bands;
|
||||
|
||||
data = iwl_acpi_get_object(fwrt->dev, ACPI_EWRD_METHOD);
|
||||
if (IS_ERR(data))
|
||||
@ -573,7 +565,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
num_chains = ACPI_SAR_NUM_CHAINS_REV2;
|
||||
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2;
|
||||
|
||||
goto read_table;
|
||||
@ -589,7 +580,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
num_chains = ACPI_SAR_NUM_CHAINS_REV1;
|
||||
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1;
|
||||
|
||||
goto read_table;
|
||||
@ -605,7 +595,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt)
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
num_chains = ACPI_SAR_NUM_CHAINS_REV0;
|
||||
num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0;
|
||||
|
||||
goto read_table;
|
||||
@ -637,23 +626,54 @@ read_table:
|
||||
/* the tables start at element 3 */
|
||||
pos = 3;
|
||||
|
||||
BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV0 != ACPI_SAR_NUM_CHAINS_REV1);
|
||||
BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV2 != 2 * ACPI_SAR_NUM_CHAINS_REV0);
|
||||
|
||||
/* parse non-cdb chains for all profiles */
|
||||
for (i = 0; i < n_profiles; i++) {
|
||||
union acpi_object *table = &wifi_pkg->package.elements[pos];
|
||||
|
||||
/* The EWRD profiles officially go from 2 to 4, but we
|
||||
* save them in sar_profiles[1-3] (because we don't
|
||||
* have profile 0). So in the array we start from 1.
|
||||
*/
|
||||
ret = iwl_acpi_sar_set_profile(table,
|
||||
&fwrt->sar_profiles[i + 1],
|
||||
enabled, num_chains,
|
||||
num_sub_bands);
|
||||
ret = iwl_acpi_parse_chains_table(table,
|
||||
fwrt->sar_profiles[i + 1].chains,
|
||||
ACPI_SAR_NUM_CHAINS_REV0,
|
||||
num_sub_bands);
|
||||
if (ret < 0)
|
||||
break;
|
||||
goto out_free;
|
||||
|
||||
/* go to the next table */
|
||||
pos += num_chains * num_sub_bands;
|
||||
pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands;
|
||||
}
|
||||
|
||||
/* non-cdb table revisions */
|
||||
if (tbl_rev < 2)
|
||||
goto set_enabled;
|
||||
|
||||
/* parse cdb chains for all profiles */
|
||||
for (i = 0; i < n_profiles; i++) {
|
||||
struct iwl_sar_profile_chain *chains;
|
||||
union acpi_object *table;
|
||||
|
||||
table = &wifi_pkg->package.elements[pos];
|
||||
chains = &fwrt->sar_profiles[i + 1].chains[ACPI_SAR_NUM_CHAINS_REV0];
|
||||
ret = iwl_acpi_parse_chains_table(table,
|
||||
chains,
|
||||
ACPI_SAR_NUM_CHAINS_REV0,
|
||||
num_sub_bands);
|
||||
if (ret < 0)
|
||||
goto out_free;
|
||||
|
||||
/* go to the next table */
|
||||
pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands;
|
||||
}
|
||||
|
||||
set_enabled:
|
||||
for (i = 0; i < n_profiles; i++)
|
||||
fwrt->sar_profiles[i + 1].enabled = enabled;
|
||||
|
||||
out_free:
|
||||
kfree(data);
|
||||
return ret;
|
||||
|
@ -39,10 +39,12 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans,
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_runtime_init);
|
||||
|
||||
/* Assumes the appropriate lock is held by the caller */
|
||||
void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt)
|
||||
{
|
||||
iwl_fw_suspend_timestamp(fwrt);
|
||||
iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, NULL);
|
||||
iwl_dbg_tlv_time_point_sync(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START,
|
||||
NULL);
|
||||
}
|
||||
IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend);
|
||||
|
||||
|
@ -1413,26 +1413,36 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op)
|
||||
const struct iwl_op_mode_ops *ops = op->ops;
|
||||
struct dentry *dbgfs_dir = NULL;
|
||||
struct iwl_op_mode *op_mode = NULL;
|
||||
int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY;
|
||||
|
||||
/* also protects start/stop from racing against each other */
|
||||
lockdep_assert_held(&iwlwifi_opmode_table_mtx);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
|
||||
drv->dbgfs_drv);
|
||||
dbgfs_dir = drv->dbgfs_op_mode;
|
||||
#endif
|
||||
|
||||
op_mode = ops->start(drv->trans, drv->trans->cfg,
|
||||
&drv->fw, dbgfs_dir);
|
||||
if (op_mode)
|
||||
return op_mode;
|
||||
for (retry = 0; retry <= max_retry; retry++) {
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
debugfs_remove_recursive(drv->dbgfs_op_mode);
|
||||
drv->dbgfs_op_mode = NULL;
|
||||
drv->dbgfs_op_mode = debugfs_create_dir(op->name,
|
||||
drv->dbgfs_drv);
|
||||
dbgfs_dir = drv->dbgfs_op_mode;
|
||||
#endif
|
||||
|
||||
op_mode = ops->start(drv->trans, drv->trans->cfg,
|
||||
&drv->fw, dbgfs_dir);
|
||||
|
||||
if (op_mode)
|
||||
return op_mode;
|
||||
|
||||
if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status))
|
||||
break;
|
||||
|
||||
IWL_ERR(drv, "retry init count %d\n", retry);
|
||||
|
||||
#ifdef CONFIG_IWLWIFI_DEBUGFS
|
||||
debugfs_remove_recursive(drv->dbgfs_op_mode);
|
||||
drv->dbgfs_op_mode = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,9 @@ void iwl_drv_stop(struct iwl_drv *drv);
|
||||
#define VISIBLE_IF_IWLWIFI_KUNIT static
|
||||
#endif
|
||||
|
||||
/* max retry for init flow */
|
||||
#define IWL_MAX_INIT_RETRY 2
|
||||
|
||||
#define FW_NAME_PRE_BUFSIZE 64
|
||||
struct iwl_trans;
|
||||
const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf);
|
||||
|
@ -1398,7 +1398,9 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan)
|
||||
|
||||
iwl_mvm_pause_tcm(mvm, true);
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
iwl_fw_runtime_suspend(&mvm->fwrt);
|
||||
mutex_unlock(&mvm->mutex);
|
||||
|
||||
return __iwl_mvm_suspend(hw, wowlan, false);
|
||||
}
|
||||
|
@ -1307,8 +1307,8 @@ static void iwl_mvm_disconnect_iterator(void *data, u8 *mac,
|
||||
void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
{
|
||||
u32 error_log_size = mvm->fw->ucode_capa.error_log_size;
|
||||
u32 status = 0;
|
||||
int ret;
|
||||
u32 resp;
|
||||
|
||||
struct iwl_fw_error_recovery_cmd recovery_cmd = {
|
||||
.flags = cpu_to_le32(flags),
|
||||
@ -1316,7 +1316,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
};
|
||||
struct iwl_host_cmd host_cmd = {
|
||||
.id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD),
|
||||
.flags = CMD_WANT_SKB,
|
||||
.data = {&recovery_cmd, },
|
||||
.len = {sizeof(recovery_cmd), },
|
||||
};
|
||||
@ -1336,7 +1335,7 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
recovery_cmd.buf_size = cpu_to_le32(error_log_size);
|
||||
}
|
||||
|
||||
ret = iwl_mvm_send_cmd(mvm, &host_cmd);
|
||||
ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status);
|
||||
kfree(mvm->error_recovery_buf);
|
||||
mvm->error_recovery_buf = NULL;
|
||||
|
||||
@ -1347,11 +1346,10 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags)
|
||||
|
||||
/* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */
|
||||
if (flags & ERROR_RECOVERY_UPDATE_DB) {
|
||||
resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data);
|
||||
if (resp) {
|
||||
if (status) {
|
||||
IWL_ERR(mvm,
|
||||
"Failed to send recovery cmd blob was invalid %d\n",
|
||||
resp);
|
||||
status);
|
||||
|
||||
ieee80211_iterate_interfaces(mvm->hw, 0,
|
||||
iwl_mvm_disconnect_iterator,
|
||||
|
@ -1293,12 +1293,14 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)
|
||||
{
|
||||
struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
|
||||
int ret;
|
||||
int retry, max_retry = 0;
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
/* we are starting the mac not in error flow, and restart is enabled */
|
||||
if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) &&
|
||||
iwlwifi_mod_params.fw_restart) {
|
||||
max_retry = IWL_MAX_INIT_RETRY;
|
||||
/*
|
||||
* This will prevent mac80211 recovery flows to trigger during
|
||||
* init failures
|
||||
@ -1306,7 +1308,13 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw)
|
||||
set_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
|
||||
}
|
||||
|
||||
ret = __iwl_mvm_mac_start(mvm);
|
||||
for (retry = 0; retry <= max_retry; retry++) {
|
||||
ret = __iwl_mvm_mac_start(mvm);
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
IWL_ERR(mvm, "mac start retry %d\n", retry);
|
||||
}
|
||||
clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status);
|
||||
|
||||
mutex_unlock(&mvm->mutex);
|
||||
@ -1970,7 +1978,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
|
||||
mvm->p2p_device_vif = NULL;
|
||||
}
|
||||
|
||||
iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
|
||||
iwl_mvm_mac_ctxt_remove(mvm, vif);
|
||||
|
||||
RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL);
|
||||
@ -1979,6 +1986,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw,
|
||||
mvm->monitor_on = false;
|
||||
|
||||
out:
|
||||
iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf);
|
||||
if (vif->type == NL80211_IFTYPE_AP ||
|
||||
vif->type == NL80211_IFTYPE_ADHOC) {
|
||||
iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta);
|
||||
|
@ -41,8 +41,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
|
||||
/* reset deflink MLO parameters */
|
||||
mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID;
|
||||
mvmvif->deflink.active = 0;
|
||||
/* the first link always points to the default one */
|
||||
mvmvif->link[0] = &mvmvif->deflink;
|
||||
|
||||
ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif);
|
||||
if (ret)
|
||||
@ -60,9 +58,19 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw,
|
||||
IEEE80211_VIF_SUPPORTS_CQM_RSSI;
|
||||
}
|
||||
|
||||
ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf);
|
||||
if (ret)
|
||||
goto out_free_bf;
|
||||
/* We want link[0] to point to the default link, unless we have MLO and
|
||||
* in this case this will be modified later by .change_vif_links()
|
||||
* If we are in the restart flow with an MLD connection, we will wait
|
||||
* to .change_vif_links() to setup the links.
|
||||
*/
|
||||
if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) ||
|
||||
!ieee80211_vif_is_mld(vif)) {
|
||||
mvmvif->link[0] = &mvmvif->deflink;
|
||||
|
||||
ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf);
|
||||
if (ret)
|
||||
goto out_free_bf;
|
||||
}
|
||||
|
||||
/* Save a pointer to p2p device vif, so it can later be used to
|
||||
* update the p2p device MAC when a GO is started/stopped
|
||||
@ -350,11 +358,6 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif,
|
||||
link_conf,
|
||||
false);
|
||||
|
||||
/* then activate */
|
||||
ret = iwl_mvm_link_changed(mvm, vif, link_conf,
|
||||
LINK_CONTEXT_MODIFY_ACTIVE |
|
||||
@ -363,6 +366,11 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
if (vif->type == NL80211_IFTYPE_STATION)
|
||||
iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif,
|
||||
link_conf,
|
||||
false);
|
||||
|
||||
/*
|
||||
* Power state must be updated before quotas,
|
||||
* otherwise fw will complain.
|
||||
@ -1194,7 +1202,11 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw,
|
||||
|
||||
mutex_lock(&mvm->mutex);
|
||||
|
||||
if (old_links == 0) {
|
||||
/* If we're in RESTART flow, the default link wasn't added in
|
||||
* drv_add_interface(), and link[0] doesn't point to it.
|
||||
*/
|
||||
if (old_links == 0 && !test_bit(IWL_MVM_STATUS_IN_HW_RESTART,
|
||||
&mvm->status)) {
|
||||
err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf);
|
||||
if (err)
|
||||
goto out_err;
|
||||
|
@ -1774,7 +1774,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
|
||||
&cp->channel_config[ch_cnt];
|
||||
|
||||
u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0;
|
||||
u8 j, k, n_s_ssids = 0, n_bssids = 0;
|
||||
u8 k, n_s_ssids = 0, n_bssids = 0;
|
||||
u8 max_s_ssids, max_bssids;
|
||||
bool force_passive = false, found = false, allow_passive = true,
|
||||
unsolicited_probe_on_chan = false, psc_no_listen = false;
|
||||
@ -1799,7 +1799,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
|
||||
cfg->v5.iter_count = 1;
|
||||
cfg->v5.iter_interval = 0;
|
||||
|
||||
for (j = 0; j < params->n_6ghz_params; j++) {
|
||||
for (u32 j = 0; j < params->n_6ghz_params; j++) {
|
||||
s8 tmp_psd_20;
|
||||
|
||||
if (!(scan_6ghz_params[j].channel_idx == i))
|
||||
@ -1873,7 +1873,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm,
|
||||
* SSID.
|
||||
* TODO: improve this logic
|
||||
*/
|
||||
for (j = 0; j < params->n_6ghz_params; j++) {
|
||||
for (u32 j = 0; j < params->n_6ghz_params; j++) {
|
||||
if (!(scan_6ghz_params[j].channel_idx == i))
|
||||
continue;
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#include <net/ieee80211_radiotap.h>
|
||||
|
||||
struct tx_radiotap_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 rate;
|
||||
u8 txpower;
|
||||
u8 rts_retries;
|
||||
@ -31,7 +31,7 @@ struct tx_radiotap_hdr {
|
||||
#define IEEE80211_FC_DSTODS 0x0300
|
||||
|
||||
struct rx_radiotap_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 flags;
|
||||
u8 rate;
|
||||
u8 antsignal;
|
||||
|
@ -84,13 +84,16 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb,
|
||||
mutex_lock(&dev->mcu.mutex);
|
||||
|
||||
if (dev->mcu_ops->mcu_skb_prepare_msg) {
|
||||
orig_skb = skb;
|
||||
ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
}
|
||||
|
||||
retry:
|
||||
orig_skb = skb_get(skb);
|
||||
/* orig skb might be needed for retry, mcu_skb_send_msg consumes it */
|
||||
if (orig_skb)
|
||||
skb_get(orig_skb);
|
||||
ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
@ -105,7 +108,7 @@ retry:
|
||||
do {
|
||||
skb = mt76_mcu_get_response(dev, expires);
|
||||
if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) &&
|
||||
retry++ < dev->mcu_ops->max_retry) {
|
||||
orig_skb && retry++ < dev->mcu_ops->max_retry) {
|
||||
dev_err(dev->dev, "Retry message %08x (seq %d)\n",
|
||||
cmd, seq);
|
||||
skb = orig_skb;
|
||||
|
@ -7,12 +7,12 @@
|
||||
#include "cfg80211.h"
|
||||
|
||||
struct wilc_wfi_radiotap_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 rate;
|
||||
} __packed;
|
||||
|
||||
struct wilc_wfi_radiotap_cb_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 rate;
|
||||
u8 dump;
|
||||
u16 tx_flags;
|
||||
|
@ -352,7 +352,6 @@ static const struct usb_device_id rtl8192d_usb_ids[] = {
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8194, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8111, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x0193, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8171, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0xe194, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(0x2019, 0xab2c, rtl92du_hal_cfg)},
|
||||
{RTL_USB_DEVICE(0x2019, 0xab2d, rtl92du_hal_cfg)},
|
||||
|
@ -771,7 +771,6 @@ static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable)
|
||||
u8 size, timeout;
|
||||
u16 val16;
|
||||
|
||||
rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC);
|
||||
rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN);
|
||||
rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7));
|
||||
|
||||
|
@ -6445,6 +6445,8 @@ static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid)
|
||||
|
||||
/* todo DBCC related event */
|
||||
rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] wl_info phy_now=%d\n", phy_now);
|
||||
rtw89_debug(rtwdev, RTW89_DBG_BTC,
|
||||
"[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g);
|
||||
|
||||
if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) {
|
||||
wl_rinfo->dbcc_chg = 1;
|
||||
|
@ -3026,23 +3026,53 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev,
|
||||
pci_disable_device(pdev);
|
||||
}
|
||||
|
||||
static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
|
||||
static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
const struct rtw89_chip_info *chip = rtwdev->chip;
|
||||
|
||||
if (!rtwpci->enable_dac)
|
||||
return;
|
||||
|
||||
switch (chip->chip_id) {
|
||||
case RTL8852A:
|
||||
case RTL8852B:
|
||||
case RTL8851B:
|
||||
case RTL8852BT:
|
||||
break;
|
||||
return true;
|
||||
default:
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev);
|
||||
|
||||
if (!rtw89_pci_chip_is_manual_dac(rtwdev))
|
||||
return true;
|
||||
|
||||
if (!bridge)
|
||||
return false;
|
||||
|
||||
switch (bridge->vendor) {
|
||||
case PCI_VENDOR_ID_INTEL:
|
||||
return true;
|
||||
case PCI_VENDOR_ID_ASMEDIA:
|
||||
if (bridge->device == 0x2806)
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev)
|
||||
{
|
||||
struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv;
|
||||
|
||||
if (!rtwpci->enable_dac)
|
||||
return;
|
||||
|
||||
if (!rtw89_pci_chip_is_manual_dac(rtwdev))
|
||||
return;
|
||||
|
||||
rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS);
|
||||
}
|
||||
@ -3061,6 +3091,9 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!rtw89_pci_is_dac_compatible_bridge(rtwdev))
|
||||
goto no_dac;
|
||||
|
||||
ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36));
|
||||
if (!ret) {
|
||||
rtwpci->enable_dac = true;
|
||||
@ -3073,6 +3106,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev,
|
||||
goto err_release_regions;
|
||||
}
|
||||
}
|
||||
no_dac:
|
||||
|
||||
resource_len = pci_resource_len(pdev, bar_id);
|
||||
rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len);
|
||||
|
@ -763,7 +763,7 @@ static const struct rhashtable_params hwsim_rht_params = {
|
||||
};
|
||||
|
||||
struct hwsim_radiotap_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
__le64 rt_tsft;
|
||||
u8 rt_flags;
|
||||
u8 rt_rate;
|
||||
@ -772,7 +772,7 @@ struct hwsim_radiotap_hdr {
|
||||
} __packed;
|
||||
|
||||
struct hwsim_radiotap_ack_hdr {
|
||||
struct ieee80211_radiotap_header hdr;
|
||||
struct ieee80211_radiotap_header_fixed hdr;
|
||||
u8 rt_flags;
|
||||
u8 pad;
|
||||
__le16 rt_channel;
|
||||
|
@ -6129,6 +6129,50 @@ void wiphy_delayed_work_cancel(struct wiphy *wiphy,
|
||||
void wiphy_delayed_work_flush(struct wiphy *wiphy,
|
||||
struct wiphy_delayed_work *dwork);
|
||||
|
||||
/**
|
||||
* wiphy_delayed_work_pending - Find out whether a wiphy delayable
|
||||
* work item is currently pending.
|
||||
*
|
||||
* @wiphy: the wiphy, for debug purposes
|
||||
* @dwork: the delayed work in question
|
||||
*
|
||||
* Return: true if timer is pending, false otherwise
|
||||
*
|
||||
* How wiphy_delayed_work_queue() works is by setting a timer which
|
||||
* when it expires calls wiphy_work_queue() to queue the wiphy work.
|
||||
* Because wiphy_delayed_work_queue() uses mod_timer(), if it is
|
||||
* called twice and the second call happens before the first call
|
||||
* deadline, the work will rescheduled for the second deadline and
|
||||
* won't run before that.
|
||||
*
|
||||
* wiphy_delayed_work_pending() can be used to detect if calling
|
||||
* wiphy_work_delayed_work_queue() would start a new work schedule
|
||||
* or delayed a previous one. As seen below it cannot be used to
|
||||
* detect precisely if the work has finished to execute nor if it
|
||||
* is currently executing.
|
||||
*
|
||||
* CPU0 CPU1
|
||||
* wiphy_delayed_work_queue(wk)
|
||||
* mod_timer(wk->timer)
|
||||
* wiphy_delayed_work_pending(wk) -> true
|
||||
*
|
||||
* [...]
|
||||
* expire_timers(wk->timer)
|
||||
* detach_timer(wk->timer)
|
||||
* wiphy_delayed_work_pending(wk) -> false
|
||||
* wk->timer->function() |
|
||||
* wiphy_work_queue(wk) | delayed work pending
|
||||
* list_add_tail() | returns false but
|
||||
* queue_work(cfg80211_wiphy_work) | wk->func() has not
|
||||
* | been run yet
|
||||
* [...] |
|
||||
* cfg80211_wiphy_work() |
|
||||
* wk->func() V
|
||||
*
|
||||
*/
|
||||
bool wiphy_delayed_work_pending(struct wiphy *wiphy,
|
||||
struct wiphy_delayed_work *dwork);
|
||||
|
||||
/**
|
||||
* enum ieee80211_ap_reg_power - regulatory power for an Access Point
|
||||
*
|
||||
|
@ -24,25 +24,27 @@
|
||||
* struct ieee80211_radiotap_header - base radiotap header
|
||||
*/
|
||||
struct ieee80211_radiotap_header {
|
||||
/**
|
||||
* @it_version: radiotap version, always 0
|
||||
*/
|
||||
uint8_t it_version;
|
||||
__struct_group(ieee80211_radiotap_header_fixed, hdr, __packed,
|
||||
/**
|
||||
* @it_version: radiotap version, always 0
|
||||
*/
|
||||
uint8_t it_version;
|
||||
|
||||
/**
|
||||
* @it_pad: padding (or alignment)
|
||||
*/
|
||||
uint8_t it_pad;
|
||||
/**
|
||||
* @it_pad: padding (or alignment)
|
||||
*/
|
||||
uint8_t it_pad;
|
||||
|
||||
/**
|
||||
* @it_len: overall radiotap header length
|
||||
*/
|
||||
__le16 it_len;
|
||||
/**
|
||||
* @it_len: overall radiotap header length
|
||||
*/
|
||||
__le16 it_len;
|
||||
|
||||
/**
|
||||
* @it_present: (first) present word
|
||||
*/
|
||||
__le32 it_present;
|
||||
/**
|
||||
* @it_present: (first) present word
|
||||
*/
|
||||
__le32 it_present;
|
||||
);
|
||||
|
||||
/**
|
||||
* @it_optional: all remaining presence bitmaps
|
||||
@ -50,6 +52,9 @@ struct ieee80211_radiotap_header {
|
||||
__le32 it_optional[];
|
||||
} __packed;
|
||||
|
||||
static_assert(offsetof(struct ieee80211_radiotap_header, it_optional) == sizeof(struct ieee80211_radiotap_header_fixed),
|
||||
"struct member likely outside of __struct_group()");
|
||||
|
||||
/* version is always 0 */
|
||||
#define PKTHDR_RADIOTAP_VERSION 0
|
||||
|
||||
|
@ -354,7 +354,7 @@ static inline void ip_tunnel_init_flow(struct flowi4 *fl4,
|
||||
memset(fl4, 0, sizeof(*fl4));
|
||||
|
||||
if (oif) {
|
||||
fl4->flowi4_l3mdev = l3mdev_master_upper_ifindex_by_index_rcu(net, oif);
|
||||
fl4->flowi4_l3mdev = l3mdev_master_upper_ifindex_by_index(net, oif);
|
||||
/* Legacy VRF/l3mdev use case */
|
||||
fl4->flowi4_oif = fl4->flowi4_l3mdev ? 0 : oif;
|
||||
}
|
||||
|
@ -206,6 +206,12 @@ struct sk_buff *__hci_cmd_sync_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
/* If command return a status event skb will be set to NULL as there are
|
||||
* no parameters.
|
||||
*/
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENODATA);
|
||||
|
||||
return skb;
|
||||
}
|
||||
EXPORT_SYMBOL(__hci_cmd_sync_sk);
|
||||
@ -255,6 +261,11 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
|
||||
u8 status;
|
||||
|
||||
skb = __hci_cmd_sync_sk(hdev, opcode, plen, param, event, timeout, sk);
|
||||
|
||||
/* If command return a status event, skb will be set to -ENODATA */
|
||||
if (skb == ERR_PTR(-ENODATA))
|
||||
return 0;
|
||||
|
||||
if (IS_ERR(skb)) {
|
||||
if (!event)
|
||||
bt_dev_err(hdev, "Opcode 0x%4.4x failed: %ld", opcode,
|
||||
@ -262,13 +273,6 @@ int __hci_cmd_sync_status_sk(struct hci_dev *hdev, u16 opcode, u32 plen,
|
||||
return PTR_ERR(skb);
|
||||
}
|
||||
|
||||
/* If command return a status event skb will be set to NULL as there are
|
||||
* no parameters, in case of failure IS_ERR(skb) would have be set to
|
||||
* the actual error would be found with PTR_ERR(skb).
|
||||
*/
|
||||
if (!skb)
|
||||
return 0;
|
||||
|
||||
status = skb->data[0];
|
||||
|
||||
kfree_skb(skb);
|
||||
|
@ -3639,6 +3639,9 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
|
||||
return 0;
|
||||
|
||||
if (features & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM)) {
|
||||
if (vlan_get_protocol(skb) == htons(ETH_P_IPV6) &&
|
||||
skb_network_header_len(skb) != sizeof(struct ipv6hdr))
|
||||
goto sw_checksum;
|
||||
switch (skb->csum_offset) {
|
||||
case offsetof(struct tcphdr, check):
|
||||
case offsetof(struct udphdr, check):
|
||||
@ -3646,6 +3649,7 @@ int skb_csum_hwoffload_help(struct sk_buff *skb,
|
||||
}
|
||||
}
|
||||
|
||||
sw_checksum:
|
||||
return skb_checksum_help(skb);
|
||||
}
|
||||
EXPORT_SYMBOL(skb_csum_hwoffload_help);
|
||||
|
@ -2032,7 +2032,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
|
||||
[IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 },
|
||||
[IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 },
|
||||
[IFLA_GSO_MAX_SEGS] = { .type = NLA_U32 },
|
||||
[IFLA_GSO_MAX_SIZE] = { .type = NLA_U32 },
|
||||
[IFLA_GSO_MAX_SIZE] = NLA_POLICY_MIN(NLA_U32, MAX_TCP_HEADER + 1),
|
||||
[IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
|
||||
[IFLA_CARRIER_CHANGES] = { .type = NLA_U32 }, /* ignored */
|
||||
[IFLA_PHYS_SWITCH_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_ITEM_ID_LEN },
|
||||
@ -2057,7 +2057,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
|
||||
[IFLA_TSO_MAX_SIZE] = { .type = NLA_REJECT },
|
||||
[IFLA_TSO_MAX_SEGS] = { .type = NLA_REJECT },
|
||||
[IFLA_ALLMULTI] = { .type = NLA_REJECT },
|
||||
[IFLA_GSO_IPV4_MAX_SIZE] = { .type = NLA_U32 },
|
||||
[IFLA_GSO_IPV4_MAX_SIZE] = NLA_POLICY_MIN(NLA_U32, MAX_TCP_HEADER + 1),
|
||||
[IFLA_GRO_IPV4_MAX_SIZE] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
|
@ -218,7 +218,7 @@ static struct ip_tunnel *ip_tunnel_find(struct ip_tunnel_net *itn,
|
||||
|
||||
ip_tunnel_flags_copy(flags, parms->i_flags);
|
||||
|
||||
hlist_for_each_entry_rcu(t, head, hash_node) {
|
||||
hlist_for_each_entry_rcu(t, head, hash_node, lockdep_rtnl_is_held()) {
|
||||
if (local == t->parms.iph.saddr &&
|
||||
remote == t->parms.iph.daddr &&
|
||||
link == READ_ONCE(t->parms.link) &&
|
||||
|
@ -268,12 +268,12 @@ static int nf_reject6_fill_skb_dst(struct sk_buff *skb_in)
|
||||
void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
|
||||
int hook)
|
||||
{
|
||||
struct sk_buff *nskb;
|
||||
struct tcphdr _otcph;
|
||||
const struct tcphdr *otcph;
|
||||
unsigned int otcplen, hh_len;
|
||||
const struct ipv6hdr *oip6h = ipv6_hdr(oldskb);
|
||||
struct dst_entry *dst = NULL;
|
||||
const struct tcphdr *otcph;
|
||||
struct sk_buff *nskb;
|
||||
struct tcphdr _otcph;
|
||||
unsigned int otcplen;
|
||||
struct flowi6 fl6;
|
||||
|
||||
if ((!(ipv6_addr_type(&oip6h->saddr) & IPV6_ADDR_UNICAST)) ||
|
||||
@ -312,9 +312,8 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
|
||||
if (IS_ERR(dst))
|
||||
return;
|
||||
|
||||
hh_len = (dst->dev->hard_header_len + 15)&~15;
|
||||
nskb = alloc_skb(hh_len + 15 + dst->header_len + sizeof(struct ipv6hdr)
|
||||
+ sizeof(struct tcphdr) + dst->trailer_len,
|
||||
nskb = alloc_skb(LL_MAX_HEADER + sizeof(struct ipv6hdr) +
|
||||
sizeof(struct tcphdr) + dst->trailer_len,
|
||||
GFP_ATOMIC);
|
||||
|
||||
if (!nskb) {
|
||||
@ -327,7 +326,7 @@ void nf_send_reset6(struct net *net, struct sock *sk, struct sk_buff *oldskb,
|
||||
|
||||
nskb->mark = fl6.flowi6_mark;
|
||||
|
||||
skb_reserve(nskb, hh_len + dst->header_len);
|
||||
skb_reserve(nskb, LL_MAX_HEADER);
|
||||
nf_reject_ip6hdr_put(nskb, oldskb, IPPROTO_TCP, ip6_dst_hoplimit(dst));
|
||||
nf_reject_ip6_tcphdr_put(nskb, oldskb, otcph, otcplen);
|
||||
|
||||
|
@ -96,7 +96,7 @@ config MAC80211_DEBUGFS
|
||||
|
||||
config MAC80211_MESSAGE_TRACING
|
||||
bool "Trace all mac80211 debug messages"
|
||||
depends on MAC80211
|
||||
depends on MAC80211 && TRACING
|
||||
help
|
||||
Select this option to have mac80211 register the
|
||||
mac80211_msg trace subsystem with tracepoints to
|
||||
|
@ -3046,6 +3046,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
|
||||
enum nl80211_tx_power_setting txp_type = type;
|
||||
bool update_txp_type = false;
|
||||
bool has_monitor = false;
|
||||
int old_power = local->user_power_level;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
@ -3128,6 +3129,10 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
|
||||
}
|
||||
}
|
||||
|
||||
if (local->emulate_chanctx &&
|
||||
(old_power != local->user_power_level))
|
||||
ieee80211_hw_conf_chan(local);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3138,7 +3143,8 @@ static int ieee80211_get_tx_power(struct wiphy *wiphy,
|
||||
struct ieee80211_local *local = wiphy_priv(wiphy);
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
|
||||
|
||||
if (local->ops->get_txpower)
|
||||
if (local->ops->get_txpower &&
|
||||
(sdata->flags & IEEE80211_SDATA_IN_DRIVER))
|
||||
return drv_get_txpower(local, sdata, dbm);
|
||||
|
||||
if (local->emulate_chanctx)
|
||||
@ -4826,12 +4832,12 @@ void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
|
||||
ieee80211_color_change_finalize(link);
|
||||
}
|
||||
|
||||
void ieee80211_color_collision_detection_work(struct work_struct *work)
|
||||
void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work)
|
||||
{
|
||||
struct delayed_work *delayed_work = to_delayed_work(work);
|
||||
struct ieee80211_link_data *link =
|
||||
container_of(delayed_work, struct ieee80211_link_data,
|
||||
color_collision_detect_work);
|
||||
container_of(work, struct ieee80211_link_data,
|
||||
color_collision_detect_work.work);
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap,
|
||||
@ -4884,7 +4890,8 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
return;
|
||||
}
|
||||
|
||||
if (delayed_work_pending(&link->color_collision_detect_work)) {
|
||||
if (wiphy_delayed_work_pending(sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
@ -4893,9 +4900,9 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
/* queue the color collision detection event every 500 ms in order to
|
||||
* avoid sending too much netlink messages to userspace.
|
||||
*/
|
||||
ieee80211_queue_delayed_work(&sdata->local->hw,
|
||||
&link->color_collision_detect_work,
|
||||
msecs_to_jiffies(500));
|
||||
wiphy_delayed_work_queue(sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work,
|
||||
msecs_to_jiffies(500));
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
@ -892,9 +892,10 @@ struct ieee80211_chanctx {
|
||||
/* temporary data for search algorithm etc. */
|
||||
struct ieee80211_chan_req req;
|
||||
|
||||
struct ieee80211_chanctx_conf conf;
|
||||
|
||||
bool radar_detected;
|
||||
|
||||
/* MUST be last - ends in a flexible-array member. */
|
||||
struct ieee80211_chanctx_conf conf;
|
||||
};
|
||||
|
||||
struct mac80211_qos_map {
|
||||
@ -1053,7 +1054,7 @@ struct ieee80211_link_data {
|
||||
} csa;
|
||||
|
||||
struct wiphy_work color_change_finalize_work;
|
||||
struct delayed_work color_collision_detect_work;
|
||||
struct wiphy_delayed_work color_collision_detect_work;
|
||||
u64 color_bitmap;
|
||||
|
||||
/* context reservation -- protected with wiphy mutex */
|
||||
@ -2005,7 +2006,8 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
/* color change handling */
|
||||
void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
void ieee80211_color_collision_detection_work(struct work_struct *work);
|
||||
void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work);
|
||||
|
||||
/* interface handling */
|
||||
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
|
||||
|
@ -987,6 +987,26 @@ void ieee80211_reenable_keys(struct ieee80211_sub_if_data *sdata)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211_key_iter(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_key *key,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
struct ieee80211_sta *sta,
|
||||
struct ieee80211_key_conf *key,
|
||||
void *data),
|
||||
void *iter_data)
|
||||
{
|
||||
/* skip keys of station in removal process */
|
||||
if (key->sta && key->sta->removed)
|
||||
return;
|
||||
if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
return;
|
||||
iter(hw, vif, key->sta ? &key->sta->sta : NULL,
|
||||
&key->conf, iter_data);
|
||||
}
|
||||
|
||||
void ieee80211_iter_keys(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif,
|
||||
void (*iter)(struct ieee80211_hw *hw,
|
||||
@ -1005,16 +1025,13 @@ void ieee80211_iter_keys(struct ieee80211_hw *hw,
|
||||
if (vif) {
|
||||
sdata = vif_to_sdata(vif);
|
||||
list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
|
||||
iter(hw, &sdata->vif,
|
||||
key->sta ? &key->sta->sta : NULL,
|
||||
&key->conf, iter_data);
|
||||
ieee80211_key_iter(hw, vif, key, iter, iter_data);
|
||||
} else {
|
||||
list_for_each_entry(sdata, &local->interfaces, list)
|
||||
list_for_each_entry_safe(key, tmp,
|
||||
&sdata->key_list, list)
|
||||
iter(hw, &sdata->vif,
|
||||
key->sta ? &key->sta->sta : NULL,
|
||||
&key->conf, iter_data);
|
||||
ieee80211_key_iter(hw, &sdata->vif, key,
|
||||
iter, iter_data);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(ieee80211_iter_keys);
|
||||
@ -1031,17 +1048,8 @@ _ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
|
||||
{
|
||||
struct ieee80211_key *key;
|
||||
|
||||
list_for_each_entry_rcu(key, &sdata->key_list, list) {
|
||||
/* skip keys of station in removal process */
|
||||
if (key->sta && key->sta->removed)
|
||||
continue;
|
||||
if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
|
||||
continue;
|
||||
|
||||
iter(hw, &sdata->vif,
|
||||
key->sta ? &key->sta->sta : NULL,
|
||||
&key->conf, iter_data);
|
||||
}
|
||||
list_for_each_entry_rcu(key, &sdata->key_list, list)
|
||||
ieee80211_key_iter(hw, &sdata->vif, key, iter, iter_data);
|
||||
}
|
||||
|
||||
void ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,
|
||||
|
@ -41,8 +41,8 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_csa_finalize_work);
|
||||
wiphy_work_init(&link->color_change_finalize_work,
|
||||
ieee80211_color_change_finalize_work);
|
||||
INIT_DELAYED_WORK(&link->color_collision_detect_work,
|
||||
ieee80211_color_collision_detection_work);
|
||||
wiphy_delayed_work_init(&link->color_collision_detect_work,
|
||||
ieee80211_color_collision_detection_work);
|
||||
INIT_LIST_HEAD(&link->assigned_chanctx_list);
|
||||
INIT_LIST_HEAD(&link->reserved_chanctx_list);
|
||||
wiphy_delayed_work_init(&link->dfs_cac_timer_work,
|
||||
@ -72,7 +72,8 @@ void ieee80211_link_stop(struct ieee80211_link_data *link)
|
||||
if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
|
||||
ieee80211_mgd_stop_link(link);
|
||||
|
||||
cancel_delayed_work_sync(&link->color_collision_detect_work);
|
||||
wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
|
||||
&link->color_collision_detect_work);
|
||||
wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
||||
&link->color_change_finalize_work);
|
||||
wiphy_work_cancel(link->sdata->local->hw.wiphy,
|
||||
|
@ -167,6 +167,8 @@ static u32 ieee80211_calc_hw_conf_chan(struct ieee80211_local *local,
|
||||
}
|
||||
|
||||
power = ieee80211_chandef_max_power(&chandef);
|
||||
if (local->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
|
||||
power = min(local->user_power_level, power);
|
||||
|
||||
rcu_read_lock();
|
||||
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
|
||||
|
@ -2864,8 +2864,10 @@ static int mptcp_init_sock(struct sock *sk)
|
||||
if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net))
|
||||
return -ENOMEM;
|
||||
|
||||
rcu_read_lock();
|
||||
ret = mptcp_init_sched(mptcp_sk(sk),
|
||||
mptcp_sched_find(mptcp_get_scheduler(net)));
|
||||
rcu_read_unlock();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -904,6 +904,9 @@ static void nft_payload_set_eval(const struct nft_expr *expr,
|
||||
((priv->base != NFT_PAYLOAD_TRANSPORT_HEADER &&
|
||||
priv->base != NFT_PAYLOAD_INNER_HEADER) ||
|
||||
skb->ip_summed != CHECKSUM_PARTIAL)) {
|
||||
if (offset + priv->len > skb->len)
|
||||
goto err;
|
||||
|
||||
fsum = skb_checksum(skb, offset, priv->len, 0);
|
||||
tsum = csum_partial(src, priv->len, 0);
|
||||
|
||||
|
@ -1269,7 +1269,7 @@ struct xt_table *xt_find_table_lock(struct net *net, u_int8_t af,
|
||||
|
||||
/* and once again: */
|
||||
list_for_each_entry(t, &xt_net->tables[af], list)
|
||||
if (strcmp(t->name, name) == 0)
|
||||
if (strcmp(t->name, name) == 0 && owner == t->me)
|
||||
return t;
|
||||
|
||||
module_put(owner);
|
||||
|
@ -1518,6 +1518,7 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
|
||||
return 0;
|
||||
|
||||
err_dev_insert:
|
||||
tcf_block_offload_unbind(block, q, ei);
|
||||
err_block_offload_bind:
|
||||
tcf_chain0_head_change_cb_del(block, ei);
|
||||
err_chain0_head_change_cb_add:
|
||||
|
@ -791,7 +791,7 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len)
|
||||
drops = max_t(int, n, 0);
|
||||
rcu_read_lock();
|
||||
while ((parentid = sch->parent)) {
|
||||
if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
|
||||
if (parentid == TC_H_ROOT)
|
||||
break;
|
||||
|
||||
if (sch->flags & TCQ_F_NOPARENT)
|
||||
|
@ -1236,6 +1236,7 @@ static void _cfg80211_unregister_wdev(struct wireless_dev *wdev,
|
||||
/* deleted from the list, so can't be found from nl80211 any more */
|
||||
cqm_config = rcu_access_pointer(wdev->cqm_config);
|
||||
kfree_rcu(cqm_config, rcu_head);
|
||||
RCU_INIT_POINTER(wdev->cqm_config, NULL);
|
||||
|
||||
/*
|
||||
* Ensure that all events have been processed and
|
||||
@ -1704,6 +1705,13 @@ void wiphy_delayed_work_flush(struct wiphy *wiphy,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush);
|
||||
|
||||
bool wiphy_delayed_work_pending(struct wiphy *wiphy,
|
||||
struct wiphy_delayed_work *dwork)
|
||||
{
|
||||
return timer_pending(&dwork->timer);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending);
|
||||
|
||||
static int __init cfg80211_init(void)
|
||||
{
|
||||
int err;
|
||||
|
@ -3050,6 +3050,10 @@ cfg80211_parse_ml_elem_sta_data(struct wiphy *wiphy,
|
||||
freq = ieee80211_channel_to_freq_khz(ap_info->channel, band);
|
||||
data.channel = ieee80211_get_channel_khz(wiphy, freq);
|
||||
|
||||
/* Skip if RNR element specifies an unsupported channel */
|
||||
if (!data.channel)
|
||||
continue;
|
||||
|
||||
/* Skip if BSS entry generated from MBSSID or DIRECT source
|
||||
* frame data available already.
|
||||
*/
|
||||
|
@ -8,6 +8,7 @@
|
||||
ALL_TESTS="
|
||||
gre_flat
|
||||
gre_mtu_change
|
||||
gre_flat_remote_change
|
||||
"
|
||||
|
||||
NUM_NETIFS=6
|
||||
@ -44,6 +45,19 @@ gre_mtu_change()
|
||||
test_mtu_change
|
||||
}
|
||||
|
||||
gre_flat_remote_change()
|
||||
{
|
||||
flat_remote_change
|
||||
|
||||
test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 (new remote)"
|
||||
test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 (new remote)"
|
||||
|
||||
flat_remote_restore
|
||||
|
||||
test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 (old remote)"
|
||||
test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 (old remote)"
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
@ -8,6 +8,7 @@
|
||||
ALL_TESTS="
|
||||
gre_flat
|
||||
gre_mtu_change
|
||||
gre_flat_remote_change
|
||||
"
|
||||
|
||||
NUM_NETIFS=6
|
||||
@ -44,6 +45,19 @@ gre_mtu_change()
|
||||
test_mtu_change
|
||||
}
|
||||
|
||||
gre_flat_remote_change()
|
||||
{
|
||||
flat_remote_change
|
||||
|
||||
test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 with key (new remote)"
|
||||
test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 with key (new remote)"
|
||||
|
||||
flat_remote_restore
|
||||
|
||||
test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 with key (old remote)"
|
||||
test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 with key (old remote)"
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
@ -8,6 +8,7 @@
|
||||
ALL_TESTS="
|
||||
gre_flat
|
||||
gre_mtu_change
|
||||
gre_flat_remote_change
|
||||
"
|
||||
|
||||
NUM_NETIFS=6
|
||||
@ -44,6 +45,19 @@ gre_mtu_change()
|
||||
test_mtu_change gre
|
||||
}
|
||||
|
||||
gre_flat_remote_change()
|
||||
{
|
||||
flat_remote_change
|
||||
|
||||
test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 with ikey/okey (new remote)"
|
||||
test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 with ikey/okey (new remote)"
|
||||
|
||||
flat_remote_restore
|
||||
|
||||
test_traffic_ip4ip6 "GRE flat IPv4-in-IPv6 with ikey/okey (old remote)"
|
||||
test_traffic_ip6ip6 "GRE flat IPv6-in-IPv6 with ikey/okey (old remote)"
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
@ -8,6 +8,7 @@
|
||||
ALL_TESTS="
|
||||
gre_hier
|
||||
gre_mtu_change
|
||||
gre_hier_remote_change
|
||||
"
|
||||
|
||||
NUM_NETIFS=6
|
||||
@ -44,6 +45,19 @@ gre_mtu_change()
|
||||
test_mtu_change gre
|
||||
}
|
||||
|
||||
gre_hier_remote_change()
|
||||
{
|
||||
hier_remote_change
|
||||
|
||||
test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 (new remote)"
|
||||
test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 (new remote)"
|
||||
|
||||
hier_remote_restore
|
||||
|
||||
test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 (old remote)"
|
||||
test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 (old remote)"
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
@ -8,6 +8,7 @@
|
||||
ALL_TESTS="
|
||||
gre_hier
|
||||
gre_mtu_change
|
||||
gre_hier_remote_change
|
||||
"
|
||||
|
||||
NUM_NETIFS=6
|
||||
@ -44,6 +45,19 @@ gre_mtu_change()
|
||||
test_mtu_change gre
|
||||
}
|
||||
|
||||
gre_hier_remote_change()
|
||||
{
|
||||
hier_remote_change
|
||||
|
||||
test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 with key (new remote)"
|
||||
test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 with key (new remote)"
|
||||
|
||||
hier_remote_restore
|
||||
|
||||
test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 with key (old remote)"
|
||||
test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 with key (old remote)"
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
@ -8,6 +8,7 @@
|
||||
ALL_TESTS="
|
||||
gre_hier
|
||||
gre_mtu_change
|
||||
gre_hier_remote_change
|
||||
"
|
||||
|
||||
NUM_NETIFS=6
|
||||
@ -44,6 +45,19 @@ gre_mtu_change()
|
||||
test_mtu_change gre
|
||||
}
|
||||
|
||||
gre_hier_remote_change()
|
||||
{
|
||||
hier_remote_change
|
||||
|
||||
test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 with ikey/okey (new remote)"
|
||||
test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 with ikey/okey (new remote)"
|
||||
|
||||
hier_remote_restore
|
||||
|
||||
test_traffic_ip4ip6 "GRE hierarchical IPv4-in-IPv6 with ikey/okey (old remote)"
|
||||
test_traffic_ip6ip6 "GRE hierarchical IPv6-in-IPv6 with ikey/okey (old remote)"
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
pre_cleanup
|
||||
|
@ -436,3 +436,83 @@ test_mtu_change()
|
||||
check_err $?
|
||||
log_test "ping GRE IPv6, packet size 1800 after MTU change"
|
||||
}
|
||||
|
||||
topo_flat_remote_change()
|
||||
{
|
||||
local old1=$1; shift
|
||||
local new1=$1; shift
|
||||
local old2=$1; shift
|
||||
local new2=$1; shift
|
||||
|
||||
ip link set dev g1a type ip6gre local $new1 remote $new2
|
||||
__addr_add_del g1a add "$new1/128"
|
||||
__addr_add_del g1a del "$old1/128"
|
||||
ip -6 route add $new2/128 via 2001:db8:10::2
|
||||
ip -6 route del $old2/128
|
||||
|
||||
ip link set dev g2a type ip6gre local $new2 remote $new1
|
||||
__addr_add_del g2a add "$new2/128"
|
||||
__addr_add_del g2a del "$old2/128"
|
||||
ip -6 route add vrf v$ol2 $new1/128 via 2001:db8:10::1
|
||||
ip -6 route del vrf v$ol2 $old1/128
|
||||
}
|
||||
|
||||
flat_remote_change()
|
||||
{
|
||||
local old1=2001:db8:3::1
|
||||
local new1=2001:db8:3::10
|
||||
local old2=2001:db8:3::2
|
||||
local new2=2001:db8:3::20
|
||||
|
||||
topo_flat_remote_change $old1 $new1 $old2 $new2
|
||||
}
|
||||
|
||||
flat_remote_restore()
|
||||
{
|
||||
local old1=2001:db8:3::10
|
||||
local new1=2001:db8:3::1
|
||||
local old2=2001:db8:3::20
|
||||
local new2=2001:db8:3::2
|
||||
|
||||
topo_flat_remote_change $old1 $new1 $old2 $new2
|
||||
}
|
||||
|
||||
topo_hier_remote_change()
|
||||
{
|
||||
local old1=$1; shift
|
||||
local new1=$1; shift
|
||||
local old2=$1; shift
|
||||
local new2=$1; shift
|
||||
|
||||
__addr_add_del dummy1 del "$old1/64"
|
||||
__addr_add_del dummy1 add "$new1/64"
|
||||
ip link set dev g1a type ip6gre local $new1 remote $new2
|
||||
ip -6 route add vrf v$ul1 $new2/128 via 2001:db8:10::2
|
||||
ip -6 route del vrf v$ul1 $old2/128
|
||||
|
||||
__addr_add_del dummy2 del "$old2/64"
|
||||
__addr_add_del dummy2 add "$new2/64"
|
||||
ip link set dev g2a type ip6gre local $new2 remote $new1
|
||||
ip -6 route add vrf v$ul2 $new1/128 via 2001:db8:10::1
|
||||
ip -6 route del vrf v$ul2 $old1/128
|
||||
}
|
||||
|
||||
hier_remote_change()
|
||||
{
|
||||
local old1=2001:db8:3::1
|
||||
local new1=2001:db8:3::10
|
||||
local old2=2001:db8:3::2
|
||||
local new2=2001:db8:3::20
|
||||
|
||||
topo_hier_remote_change $old1 $new1 $old2 $new2
|
||||
}
|
||||
|
||||
hier_remote_restore()
|
||||
{
|
||||
local old1=2001:db8:3::10
|
||||
local new1=2001:db8:3::1
|
||||
local old2=2001:db8:3::20
|
||||
local new2=2001:db8:3::2
|
||||
|
||||
topo_hier_remote_change $old1 $new1 $old2 $new2
|
||||
}
|
||||
|
@ -259,6 +259,15 @@ check_mptcp_disabled()
|
||||
mptcp_lib_ns_init disabled_ns
|
||||
|
||||
print_larger_title "New MPTCP socket can be blocked via sysctl"
|
||||
|
||||
# mainly to cover more code
|
||||
if ! ip netns exec ${disabled_ns} sysctl net.mptcp >/dev/null; then
|
||||
mptcp_lib_pr_fail "not able to list net.mptcp sysctl knobs"
|
||||
mptcp_lib_result_fail "not able to list net.mptcp sysctl knobs"
|
||||
ret=${KSFT_FAIL}
|
||||
return 1
|
||||
fi
|
||||
|
||||
# net.mptcp.enabled should be enabled by default
|
||||
if [ "$(ip netns exec ${disabled_ns} sysctl net.mptcp.enabled | awk '{ print $3 }')" -ne 1 ]; then
|
||||
mptcp_lib_pr_fail "net.mptcp.enabled sysctl is not 1 by default"
|
||||
|
@ -98,7 +98,7 @@ static int conntrack_data_insert(struct mnl_socket *sock, struct nlmsghdr *nlh,
|
||||
char buf[MNL_SOCKET_BUFFER_SIZE];
|
||||
struct nlmsghdr *rplnlh;
|
||||
unsigned int portid;
|
||||
int err, ret;
|
||||
int ret;
|
||||
|
||||
portid = mnl_socket_get_portid(sock);
|
||||
|
||||
@ -217,7 +217,7 @@ static int conntracK_count_zone(struct mnl_socket *sock, uint16_t zone)
|
||||
struct nfgenmsg *nfh;
|
||||
struct nlattr *nest;
|
||||
unsigned int portid;
|
||||
int err, ret;
|
||||
int ret;
|
||||
|
||||
portid = mnl_socket_get_portid(sock);
|
||||
|
||||
@ -264,7 +264,7 @@ static int conntrack_flush_zone(struct mnl_socket *sock, uint16_t zone)
|
||||
struct nfgenmsg *nfh;
|
||||
struct nlattr *nest;
|
||||
unsigned int portid;
|
||||
int err, ret;
|
||||
int ret;
|
||||
|
||||
portid = mnl_socket_get_portid(sock);
|
||||
|
||||
|
@ -71,6 +71,8 @@ omtu=9000
|
||||
lmtu=1500
|
||||
rmtu=2000
|
||||
|
||||
filesize=$((2 * 1024 * 1024))
|
||||
|
||||
usage(){
|
||||
echo "nft_flowtable.sh [OPTIONS]"
|
||||
echo
|
||||
@ -81,12 +83,13 @@ usage(){
|
||||
exit 1
|
||||
}
|
||||
|
||||
while getopts "o:l:r:" o
|
||||
while getopts "o:l:r:s:" o
|
||||
do
|
||||
case $o in
|
||||
o) omtu=$OPTARG;;
|
||||
l) lmtu=$OPTARG;;
|
||||
r) rmtu=$OPTARG;;
|
||||
s) filesize=$OPTARG;;
|
||||
*) usage;;
|
||||
esac
|
||||
done
|
||||
@ -217,18 +220,10 @@ ns2out=$(mktemp)
|
||||
|
||||
make_file()
|
||||
{
|
||||
name=$1
|
||||
name="$1"
|
||||
sz="$2"
|
||||
|
||||
SIZE=$((RANDOM % (1024 * 128)))
|
||||
SIZE=$((SIZE + (1024 * 8)))
|
||||
TSIZE=$((SIZE * 1024))
|
||||
|
||||
dd if=/dev/urandom of="$name" bs=1024 count=$SIZE 2> /dev/null
|
||||
|
||||
SIZE=$((RANDOM % 1024))
|
||||
SIZE=$((SIZE + 128))
|
||||
TSIZE=$((TSIZE + SIZE))
|
||||
dd if=/dev/urandom conf=notrunc of="$name" bs=1 count=$SIZE 2> /dev/null
|
||||
head -c "$sz" < /dev/urandom > "$name"
|
||||
}
|
||||
|
||||
check_counters()
|
||||
@ -246,18 +241,18 @@ check_counters()
|
||||
local fs
|
||||
fs=$(du -sb "$nsin")
|
||||
local max_orig=${fs%%/*}
|
||||
local max_repl=$((max_orig/4))
|
||||
local max_repl=$((max_orig))
|
||||
|
||||
# flowtable fastpath should bypass normal routing one, i.e. the counters in forward hook
|
||||
# should always be lower than the size of the transmitted file (max_orig).
|
||||
if [ "$orig_cnt" -gt "$max_orig" ];then
|
||||
echo "FAIL: $what: original counter $orig_cnt exceeds expected value $max_orig" 1>&2
|
||||
echo "FAIL: $what: original counter $orig_cnt exceeds expected value $max_orig, reply counter $repl_cnt" 1>&2
|
||||
ret=1
|
||||
ok=0
|
||||
fi
|
||||
|
||||
if [ "$repl_cnt" -gt $max_repl ];then
|
||||
echo "FAIL: $what: reply counter $repl_cnt exceeds expected value $max_repl" 1>&2
|
||||
echo "FAIL: $what: reply counter $repl_cnt exceeds expected value $max_repl, original counter $orig_cnt" 1>&2
|
||||
ret=1
|
||||
ok=0
|
||||
fi
|
||||
@ -455,7 +450,7 @@ test_tcp_forwarding_nat()
|
||||
return $lret
|
||||
}
|
||||
|
||||
make_file "$nsin"
|
||||
make_file "$nsin" "$filesize"
|
||||
|
||||
# First test:
|
||||
# No PMTU discovery, nsr1 is expected to fragment packets from ns1 to ns2 as needed.
|
||||
@ -664,8 +659,16 @@ if [ "$1" = "" ]; then
|
||||
l=$(((RANDOM%mtu) + low))
|
||||
r=$(((RANDOM%mtu) + low))
|
||||
|
||||
echo "re-run with random mtus: -o $o -l $l -r $r"
|
||||
$0 -o "$o" -l "$l" -r "$r"
|
||||
MINSIZE=$((2 * 1000 * 1000))
|
||||
MAXSIZE=$((64 * 1000 * 1000))
|
||||
|
||||
filesize=$(((RANDOM * RANDOM) % MAXSIZE))
|
||||
if [ "$filesize" -lt "$MINSIZE" ]; then
|
||||
filesize=$((filesize+MINSIZE))
|
||||
fi
|
||||
|
||||
echo "re-run with random mtus and file size: -o $o -l $l -r $r -s $filesize"
|
||||
$0 -o "$o" -l "$l" -r "$r" -s "$filesize"
|
||||
fi
|
||||
|
||||
exit $ret
|
||||
|
Loading…
Reference in New Issue
Block a user