Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

Pull networking fixes from David Miller:
"A little more than usual this time around. Been travelling, so that is
part of it.

Anyways, here are the highlights:

1) Deal with memcontrol races wrt. listener dismantle, from Eric
Dumazet.

2) Handle page allocation failures properly in nfp driver, from Jaku
Kicinski.

3) Fix memory leaks in macsec, from Sabrina Dubroca.

4) Fix crashes in pppol2tp_session_ioctl(), from Guillaume Nault.

5) Several fixes in bnxt_en driver, including preventing potential
NVRAM parameter corruption from Michael Chan.

6) Fix for KRACK attacks in wireless, from Johannes Berg.

7) rtnetlink event generation fixes from Xin Long.

8) Deadlock in mlxsw driver, from Ido Schimmel.

9) Disallow arithmetic operations on context pointers in bpf, from
Jakub Kicinski.

10) Missing sock_owned_by_user() check in sctp_icmp_redirect(), from
Xin Long.

11) Only TCP is supported for sockmap, make that explicit with a
check, from John Fastabend.

12) Fix IP options state races in DCCP and TCP, from Eric Dumazet.

13) Fix panic in packet_getsockopt(), also from Eric Dumazet.

14) Add missing locked in hv_sock layer, from Dexuan Cui.

15) Various aquantia bug fixes, including several statistics handling
cures. From Igor Russkikh et al.

16) Fix arithmetic overflow in devmap code, from John Fastabend.

17) Fix busted socket memory accounting when we get a fault in the tcp
zero copy paths. From Willem de Bruijn.

18) Don't leave opt->tot_len uninitialized in ipv6, from Eric Dumazet"

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (106 commits)
stmmac: Don't access tx_q->dirty_tx before netif_tx_lock
ipv6: flowlabel: do not leave opt->tot_len with garbage
of_mdio: Fix broken PHY IRQ in case of probe deferral
textsearch: fix typos in library helpers
rxrpc: Don't release call mutex on error pointer
net: stmmac: Prevent infinite loop in get_rx_timestamp_status()
net: stmmac: Fix stmmac_get_rx_hwtstamp()
net: stmmac: Add missing call to dev_kfree_skb()
mlxsw: spectrum_router: Configure TIGCR on init
mlxsw: reg: Add Tunneling IPinIP General Configuration Register
net: ethtool: remove error check for legacy setting transceiver type
soreuseport: fix initialization race
net: bridge: fix returning of vlan range op errors
sock: correct sk_wmem_queued accounting on efault in tcp zerocopy
bpf: add test cases to bpf selftests to cover all access tests
bpf: fix pattern matches for direct packet access
bpf: fix off by one for range markings with L{T, E} patterns
bpf: devmap fix arithmetic overflow in bitmap_size calculation
net: aquantia: Bad udp rate on default interrupt coalescing
net: aquantia: Enable coalescing management via ethtool interface
...

+1733 -687
+76 -15
drivers/net/can/flexcan.c
··· 182 182 /* FLEXCAN hardware feature flags 183 183 * 184 184 * Below is some version info we got: 185 - * SOC Version IP-Version Glitch- [TR]WRN_INT Memory err RTR re- 186 - * Filter? connected? detection ception in MB 187 - * MX25 FlexCAN2 03.00.00.00 no no no no 188 - * MX28 FlexCAN2 03.00.04.00 yes yes no no 189 - * MX35 FlexCAN2 03.00.00.00 no no no no 190 - * MX53 FlexCAN2 03.00.00.00 yes no no no 191 - * MX6s FlexCAN3 10.00.12.00 yes yes no yes 192 - * VF610 FlexCAN3 ? no yes yes yes? 185 + * SOC Version IP-Version Glitch- [TR]WRN_INT IRQ Err Memory err RTR re- 186 + * Filter? connected? Passive detection ception in MB 187 + * MX25 FlexCAN2 03.00.00.00 no no ? no no 188 + * MX28 FlexCAN2 03.00.04.00 yes yes no no no 189 + * MX35 FlexCAN2 03.00.00.00 no no ? no no 190 + * MX53 FlexCAN2 03.00.00.00 yes no no no no 191 + * MX6s FlexCAN3 10.00.12.00 yes yes no no yes 192 + * VF610 FlexCAN3 ? no yes ? yes yes? 193 193 * 194 194 * Some SOCs do not have the RX_WARN & TX_WARN interrupt line connected. 195 195 */ 196 - #define FLEXCAN_QUIRK_BROKEN_ERR_STATE BIT(1) /* [TR]WRN_INT not connected */ 196 + #define FLEXCAN_QUIRK_BROKEN_WERR_STATE BIT(1) /* [TR]WRN_INT not connected */ 197 197 #define FLEXCAN_QUIRK_DISABLE_RXFG BIT(2) /* Disable RX FIFO Global mask */ 198 198 #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) /* Enable EACEN and RRS bit in ctrl2 */ 199 199 #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) /* Disable Memory error detection */ 200 200 #define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) /* Use timestamp based offloading */ 201 + #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) /* No interrupt for error passive */ 201 202 202 203 /* Structure of the message buffer */ 203 204 struct flexcan_mb { ··· 282 281 }; 283 282 284 283 static const struct flexcan_devtype_data fsl_p1010_devtype_data = { 285 - .quirks = FLEXCAN_QUIRK_BROKEN_ERR_STATE, 284 + .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | 285 + FLEXCAN_QUIRK_BROKEN_PERR_STATE, 286 286 }; 287 287 288 - static const struct flexcan_devtype_data fsl_imx28_devtype_data; 288 + static const struct flexcan_devtype_data fsl_imx28_devtype_data = { 289 + .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE, 290 + }; 289 291 290 292 static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { 291 293 .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | 292 - FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, 294 + FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE, 293 295 }; 294 296 295 297 static const struct flexcan_devtype_data fsl_vf610_devtype_data = { ··· 338 334 writel(val, addr); 339 335 } 340 336 #endif 337 + 338 + static inline void flexcan_error_irq_enable(const struct flexcan_priv *priv) 339 + { 340 + struct flexcan_regs __iomem *regs = priv->regs; 341 + u32 reg_ctrl = (priv->reg_ctrl_default | FLEXCAN_CTRL_ERR_MSK); 342 + 343 + flexcan_write(reg_ctrl, &regs->ctrl); 344 + } 345 + 346 + static inline void flexcan_error_irq_disable(const struct flexcan_priv *priv) 347 + { 348 + struct flexcan_regs __iomem *regs = priv->regs; 349 + u32 reg_ctrl = (priv->reg_ctrl_default & ~FLEXCAN_CTRL_ERR_MSK); 350 + 351 + flexcan_write(reg_ctrl, &regs->ctrl); 352 + } 341 353 342 354 static inline int flexcan_transceiver_enable(const struct flexcan_priv *priv) 343 355 { ··· 733 713 struct flexcan_regs __iomem *regs = priv->regs; 734 714 irqreturn_t handled = IRQ_NONE; 735 715 u32 reg_iflag1, reg_esr; 716 + enum can_state last_state = priv->can.state; 736 717 737 718 reg_iflag1 = flexcan_read(&regs->iflag1); 738 719 ··· 786 765 flexcan_write(reg_esr & FLEXCAN_ESR_ALL_INT, &regs->esr); 787 766 } 788 767 789 - /* state change interrupt */ 790 - if (reg_esr & FLEXCAN_ESR_ERR_STATE) 768 + /* state change interrupt or broken error state quirk fix is enabled */ 769 + if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || 770 + (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | 771 + FLEXCAN_QUIRK_BROKEN_PERR_STATE))) 791 772 flexcan_irq_state(dev, reg_esr); 792 773 793 774 /* bus error IRQ - handle if bus error reporting is activated */ 794 775 if ((reg_esr & FLEXCAN_ESR_ERR_BUS) && 795 776 (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) 796 777 flexcan_irq_bus_err(dev, reg_esr); 778 + 779 + /* availability of error interrupt among state transitions in case 780 + * bus error reporting is de-activated and 781 + * FLEXCAN_QUIRK_BROKEN_PERR_STATE is enabled: 782 + * +--------------------------------------------------------------+ 783 + * | +----------------------------------------------+ [stopped / | 784 + * | | | sleeping] -+ 785 + * +-+-> active <-> warning <-> passive -> bus off -+ 786 + * ___________^^^^^^^^^^^^_______________________________ 787 + * disabled(1) enabled disabled 788 + * 789 + * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled 790 + */ 791 + if ((last_state != priv->can.state) && 792 + (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) && 793 + !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { 794 + switch (priv->can.state) { 795 + case CAN_STATE_ERROR_ACTIVE: 796 + if (priv->devtype_data->quirks & 797 + FLEXCAN_QUIRK_BROKEN_WERR_STATE) 798 + flexcan_error_irq_enable(priv); 799 + else 800 + flexcan_error_irq_disable(priv); 801 + break; 802 + 803 + case CAN_STATE_ERROR_WARNING: 804 + flexcan_error_irq_enable(priv); 805 + break; 806 + 807 + case CAN_STATE_ERROR_PASSIVE: 808 + case CAN_STATE_BUS_OFF: 809 + flexcan_error_irq_disable(priv); 810 + break; 811 + 812 + default: 813 + break; 814 + } 815 + } 797 816 798 817 return handled; 799 818 } ··· 948 887 * on most Flexcan cores, too. Otherwise we don't get 949 888 * any error warning or passive interrupts. 950 889 */ 951 - if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_ERR_STATE || 890 + if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE || 952 891 priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) 953 892 reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; 954 893 else
+1 -1
drivers/net/can/usb/esd_usb2.c
··· 333 333 } 334 334 335 335 cf->can_id = id & ESD_IDMASK; 336 - cf->can_dlc = get_can_dlc(msg->msg.rx.dlc); 336 + cf->can_dlc = get_can_dlc(msg->msg.rx.dlc & ~ESD_RTR); 337 337 338 338 if (id & ESD_EXTID) 339 339 cf->can_id |= CAN_EFF_FLAG;
+2 -8
drivers/net/can/usb/gs_usb.c
··· 375 375 376 376 gs_free_tx_context(txc); 377 377 378 + atomic_dec(&dev->active_tx_urbs); 379 + 378 380 netif_wake_queue(netdev); 379 381 } 380 382 ··· 465 463 urb->transfer_buffer_length, 466 464 urb->transfer_buffer, 467 465 urb->transfer_dma); 468 - 469 - atomic_dec(&dev->active_tx_urbs); 470 - 471 - if (!netif_device_present(netdev)) 472 - return; 473 - 474 - if (netif_queue_stopped(netdev)) 475 - netif_wake_queue(netdev); 476 466 } 477 467 478 468 static netdev_tx_t gs_can_start_xmit(struct sk_buff *skb,
+8 -2
drivers/net/dsa/mv88e6060.c
··· 214 214 215 215 static int mv88e6060_set_addr(struct dsa_switch *ds, u8 *addr) 216 216 { 217 - /* Use the same MAC Address as FD Pause frames for all ports */ 218 - REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, (addr[0] << 9) | addr[1]); 217 + u16 val = addr[0] << 8 | addr[1]; 218 + 219 + /* The multicast bit is always transmitted as a zero, so the switch uses 220 + * bit 8 for "DiffAddr", where 0 means all ports transmit the same SA. 221 + */ 222 + val &= 0xfeff; 223 + 224 + REG_WRITE(REG_GLOBAL, GLOBAL_MAC_01, val); 219 225 REG_WRITE(REG_GLOBAL, GLOBAL_MAC_23, (addr[2] << 8) | addr[3]); 220 226 REG_WRITE(REG_GLOBAL, GLOBAL_MAC_45, (addr[4] << 8) | addr[5]); 221 227
+2 -2
drivers/net/ethernet/amazon/ena/ena_ethtool.c
··· 742 742 { 743 743 struct ena_adapter *adapter = netdev_priv(netdev); 744 744 745 - channels->max_rx = ENA_MAX_NUM_IO_QUEUES; 746 - channels->max_tx = ENA_MAX_NUM_IO_QUEUES; 745 + channels->max_rx = adapter->num_queues; 746 + channels->max_tx = adapter->num_queues; 747 747 channels->max_other = 0; 748 748 channels->max_combined = 0; 749 749 channels->rx_count = adapter->num_queues;
+4 -3
drivers/net/ethernet/amazon/ena/ena_netdev.c
··· 966 966 u64_stats_update_begin(&rx_ring->syncp); 967 967 rx_ring->rx_stats.bad_csum++; 968 968 u64_stats_update_end(&rx_ring->syncp); 969 - netif_err(rx_ring->adapter, rx_err, rx_ring->netdev, 969 + netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev, 970 970 "RX IPv4 header checksum error\n"); 971 971 return; 972 972 } ··· 979 979 u64_stats_update_begin(&rx_ring->syncp); 980 980 rx_ring->rx_stats.bad_csum++; 981 981 u64_stats_update_end(&rx_ring->syncp); 982 - netif_err(rx_ring->adapter, rx_err, rx_ring->netdev, 982 + netif_dbg(rx_ring->adapter, rx_err, rx_ring->netdev, 983 983 "RX L4 checksum error\n"); 984 984 skb->ip_summed = CHECKSUM_NONE; 985 985 return; ··· 3064 3064 if (ena_dev->mem_bar) 3065 3065 devm_iounmap(&pdev->dev, ena_dev->mem_bar); 3066 3066 3067 - devm_iounmap(&pdev->dev, ena_dev->reg_bar); 3067 + if (ena_dev->reg_bar) 3068 + devm_iounmap(&pdev->dev, ena_dev->reg_bar); 3068 3069 3069 3070 release_bars = pci_select_bars(pdev, IORESOURCE_MEM) & ENA_BAR_MASK; 3070 3071 pci_release_selected_regions(pdev, release_bars);
+6 -2
drivers/net/ethernet/aquantia/atlantic/aq_cfg.h
··· 22 22 23 23 #define AQ_CFG_FORCE_LEGACY_INT 0U 24 24 25 - #define AQ_CFG_IS_INTERRUPT_MODERATION_DEF 1U 26 - #define AQ_CFG_INTERRUPT_MODERATION_RATE_DEF 0xFFFFU 25 + #define AQ_CFG_INTERRUPT_MODERATION_OFF 0 26 + #define AQ_CFG_INTERRUPT_MODERATION_ON 1 27 + #define AQ_CFG_INTERRUPT_MODERATION_AUTO 0xFFFFU 28 + 29 + #define AQ_CFG_INTERRUPT_MODERATION_USEC_MAX (0x1FF * 2) 30 + 27 31 #define AQ_CFG_IRQ_MASK 0x1FFU 28 32 29 33 #define AQ_CFG_VECS_MAX 8U
+98 -57
drivers/net/ethernet/aquantia/atlantic/aq_ethtool.c
··· 56 56 return aq_nic_set_link_ksettings(aq_nic, cmd); 57 57 } 58 58 59 - /* there "5U" is number of queue[#] stats lines (InPackets+...+InErrors) */ 60 - static const unsigned int aq_ethtool_stat_queue_lines = 5U; 61 - static const unsigned int aq_ethtool_stat_queue_chars = 62 - 5U * ETH_GSTRING_LEN; 63 59 static const char aq_ethtool_stat_names[][ETH_GSTRING_LEN] = { 64 60 "InPackets", 65 61 "InUCast", ··· 79 83 "InOctetsDma", 80 84 "OutOctetsDma", 81 85 "InDroppedDma", 82 - "Queue[0] InPackets", 83 - "Queue[0] OutPackets", 84 - "Queue[0] InJumboPackets", 85 - "Queue[0] InLroPackets", 86 - "Queue[0] InErrors", 87 - "Queue[1] InPackets", 88 - "Queue[1] OutPackets", 89 - "Queue[1] InJumboPackets", 90 - "Queue[1] InLroPackets", 91 - "Queue[1] InErrors", 92 - "Queue[2] InPackets", 93 - "Queue[2] OutPackets", 94 - "Queue[2] InJumboPackets", 95 - "Queue[2] InLroPackets", 96 - "Queue[2] InErrors", 97 - "Queue[3] InPackets", 98 - "Queue[3] OutPackets", 99 - "Queue[3] InJumboPackets", 100 - "Queue[3] InLroPackets", 101 - "Queue[3] InErrors", 102 - "Queue[4] InPackets", 103 - "Queue[4] OutPackets", 104 - "Queue[4] InJumboPackets", 105 - "Queue[4] InLroPackets", 106 - "Queue[4] InErrors", 107 - "Queue[5] InPackets", 108 - "Queue[5] OutPackets", 109 - "Queue[5] InJumboPackets", 110 - "Queue[5] InLroPackets", 111 - "Queue[5] InErrors", 112 - "Queue[6] InPackets", 113 - "Queue[6] OutPackets", 114 - "Queue[6] InJumboPackets", 115 - "Queue[6] InLroPackets", 116 - "Queue[6] InErrors", 117 - "Queue[7] InPackets", 118 - "Queue[7] OutPackets", 119 - "Queue[7] InJumboPackets", 120 - "Queue[7] InLroPackets", 121 - "Queue[7] InErrors", 86 + }; 87 + 88 + static const char aq_ethtool_queue_stat_names[][ETH_GSTRING_LEN] = { 89 + "Queue[%d] InPackets", 90 + "Queue[%d] OutPackets", 91 + "Queue[%d] Restarts", 92 + "Queue[%d] InJumboPackets", 93 + "Queue[%d] InLroPackets", 94 + "Queue[%d] InErrors", 122 95 }; 123 96 124 97 static void aq_ethtool_stats(struct net_device *ndev, 125 98 struct ethtool_stats *stats, u64 *data) 126 99 { 127 100 struct aq_nic_s *aq_nic = netdev_priv(ndev); 101 + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); 128 102 129 - /* ASSERT: Need add lines to aq_ethtool_stat_names if AQ_CFG_VECS_MAX > 8 */ 130 - BUILD_BUG_ON(AQ_CFG_VECS_MAX > 8); 131 - memset(data, 0, ARRAY_SIZE(aq_ethtool_stat_names) * sizeof(u64)); 103 + memset(data, 0, (ARRAY_SIZE(aq_ethtool_stat_names) + 104 + ARRAY_SIZE(aq_ethtool_queue_stat_names) * 105 + cfg->vecs) * sizeof(u64)); 132 106 aq_nic_get_stats(aq_nic, data); 133 107 } 134 108 ··· 120 154 121 155 strlcpy(drvinfo->bus_info, pdev ? pci_name(pdev) : "", 122 156 sizeof(drvinfo->bus_info)); 123 - drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) - 124 - (AQ_CFG_VECS_MAX - cfg->vecs) * aq_ethtool_stat_queue_lines; 157 + drvinfo->n_stats = ARRAY_SIZE(aq_ethtool_stat_names) + 158 + cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); 125 159 drvinfo->testinfo_len = 0; 126 160 drvinfo->regdump_len = regs_count; 127 161 drvinfo->eedump_len = 0; ··· 130 164 static void aq_ethtool_get_strings(struct net_device *ndev, 131 165 u32 stringset, u8 *data) 132 166 { 167 + int i, si; 133 168 struct aq_nic_s *aq_nic = netdev_priv(ndev); 134 169 struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); 170 + u8 *p = data; 135 171 136 - if (stringset == ETH_SS_STATS) 137 - memcpy(data, *aq_ethtool_stat_names, 138 - sizeof(aq_ethtool_stat_names) - 139 - (AQ_CFG_VECS_MAX - cfg->vecs) * 140 - aq_ethtool_stat_queue_chars); 172 + if (stringset == ETH_SS_STATS) { 173 + memcpy(p, *aq_ethtool_stat_names, 174 + sizeof(aq_ethtool_stat_names)); 175 + p = p + sizeof(aq_ethtool_stat_names); 176 + for (i = 0; i < cfg->vecs; i++) { 177 + for (si = 0; 178 + si < ARRAY_SIZE(aq_ethtool_queue_stat_names); 179 + si++) { 180 + snprintf(p, ETH_GSTRING_LEN, 181 + aq_ethtool_queue_stat_names[si], i); 182 + p += ETH_GSTRING_LEN; 183 + } 184 + } 185 + } 141 186 } 142 187 143 188 static int aq_ethtool_get_sset_count(struct net_device *ndev, int stringset) ··· 159 182 160 183 switch (stringset) { 161 184 case ETH_SS_STATS: 162 - ret = ARRAY_SIZE(aq_ethtool_stat_names) - 163 - (AQ_CFG_VECS_MAX - cfg->vecs) * 164 - aq_ethtool_stat_queue_lines; 185 + ret = ARRAY_SIZE(aq_ethtool_stat_names) + 186 + cfg->vecs * ARRAY_SIZE(aq_ethtool_queue_stat_names); 165 187 break; 166 188 default: 167 189 ret = -EOPNOTSUPP; ··· 221 245 return err; 222 246 } 223 247 248 + int aq_ethtool_get_coalesce(struct net_device *ndev, 249 + struct ethtool_coalesce *coal) 250 + { 251 + struct aq_nic_s *aq_nic = netdev_priv(ndev); 252 + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); 253 + 254 + if (cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON || 255 + cfg->itr == AQ_CFG_INTERRUPT_MODERATION_AUTO) { 256 + coal->rx_coalesce_usecs = cfg->rx_itr; 257 + coal->tx_coalesce_usecs = cfg->tx_itr; 258 + coal->rx_max_coalesced_frames = 0; 259 + coal->tx_max_coalesced_frames = 0; 260 + } else { 261 + coal->rx_coalesce_usecs = 0; 262 + coal->tx_coalesce_usecs = 0; 263 + coal->rx_max_coalesced_frames = 1; 264 + coal->tx_max_coalesced_frames = 1; 265 + } 266 + return 0; 267 + } 268 + 269 + int aq_ethtool_set_coalesce(struct net_device *ndev, 270 + struct ethtool_coalesce *coal) 271 + { 272 + struct aq_nic_s *aq_nic = netdev_priv(ndev); 273 + struct aq_nic_cfg_s *cfg = aq_nic_get_cfg(aq_nic); 274 + 275 + /* This is not yet supported 276 + */ 277 + if (coal->use_adaptive_rx_coalesce || coal->use_adaptive_tx_coalesce) 278 + return -EOPNOTSUPP; 279 + 280 + /* Atlantic only supports timing based coalescing 281 + */ 282 + if (coal->rx_max_coalesced_frames > 1 || 283 + coal->rx_coalesce_usecs_irq || 284 + coal->rx_max_coalesced_frames_irq) 285 + return -EOPNOTSUPP; 286 + 287 + if (coal->tx_max_coalesced_frames > 1 || 288 + coal->tx_coalesce_usecs_irq || 289 + coal->tx_max_coalesced_frames_irq) 290 + return -EOPNOTSUPP; 291 + 292 + /* We do not support frame counting. Check this 293 + */ 294 + if (!(coal->rx_max_coalesced_frames == !coal->rx_coalesce_usecs)) 295 + return -EOPNOTSUPP; 296 + if (!(coal->tx_max_coalesced_frames == !coal->tx_coalesce_usecs)) 297 + return -EOPNOTSUPP; 298 + 299 + if (coal->rx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX || 300 + coal->tx_coalesce_usecs > AQ_CFG_INTERRUPT_MODERATION_USEC_MAX) 301 + return -EINVAL; 302 + 303 + cfg->itr = AQ_CFG_INTERRUPT_MODERATION_ON; 304 + 305 + cfg->rx_itr = coal->rx_coalesce_usecs; 306 + cfg->tx_itr = coal->tx_coalesce_usecs; 307 + 308 + return aq_nic_update_interrupt_moderation_settings(aq_nic); 309 + } 310 + 224 311 const struct ethtool_ops aq_ethtool_ops = { 225 312 .get_link = aq_ethtool_get_link, 226 313 .get_regs_len = aq_ethtool_get_regs_len, ··· 298 259 .get_ethtool_stats = aq_ethtool_stats, 299 260 .get_link_ksettings = aq_ethtool_get_link_ksettings, 300 261 .set_link_ksettings = aq_ethtool_set_link_ksettings, 262 + .get_coalesce = aq_ethtool_get_coalesce, 263 + .set_coalesce = aq_ethtool_set_coalesce, 301 264 };
+3 -2
drivers/net/ethernet/aquantia/atlantic/aq_hw.h
··· 151 151 [ETH_ALEN], 152 152 u32 count); 153 153 154 - int (*hw_interrupt_moderation_set)(struct aq_hw_s *self, 155 - bool itr_enabled); 154 + int (*hw_interrupt_moderation_set)(struct aq_hw_s *self); 156 155 157 156 int (*hw_rss_set)(struct aq_hw_s *self, 158 157 struct aq_rss_parameters *rss_params); ··· 161 162 162 163 int (*hw_get_regs)(struct aq_hw_s *self, 163 164 struct aq_hw_caps_s *aq_hw_caps, u32 *regs_buff); 165 + 166 + int (*hw_update_stats)(struct aq_hw_s *self); 164 167 165 168 int (*hw_get_hw_stats)(struct aq_hw_s *self, u64 *data, 166 169 unsigned int *p_count);
+30 -9
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
··· 16 16 #include "aq_pci_func.h" 17 17 #include "aq_nic_internal.h" 18 18 19 + #include <linux/moduleparam.h> 19 20 #include <linux/netdevice.h> 20 21 #include <linux/etherdevice.h> 21 22 #include <linux/timer.h> ··· 24 23 #include <linux/ip.h> 25 24 #include <linux/tcp.h> 26 25 #include <net/ip.h> 26 + 27 + static unsigned int aq_itr = AQ_CFG_INTERRUPT_MODERATION_AUTO; 28 + module_param_named(aq_itr, aq_itr, uint, 0644); 29 + MODULE_PARM_DESC(aq_itr, "Interrupt throttling mode"); 30 + 31 + static unsigned int aq_itr_tx; 32 + module_param_named(aq_itr_tx, aq_itr_tx, uint, 0644); 33 + MODULE_PARM_DESC(aq_itr_tx, "TX interrupt throttle rate"); 34 + 35 + static unsigned int aq_itr_rx; 36 + module_param_named(aq_itr_rx, aq_itr_rx, uint, 0644); 37 + MODULE_PARM_DESC(aq_itr_rx, "RX interrupt throttle rate"); 27 38 28 39 static void aq_nic_rss_init(struct aq_nic_s *self, unsigned int num_rss_queues) 29 40 { ··· 74 61 75 62 cfg->is_polling = AQ_CFG_IS_POLLING_DEF; 76 63 77 - cfg->is_interrupt_moderation = AQ_CFG_IS_INTERRUPT_MODERATION_DEF; 78 - cfg->itr = cfg->is_interrupt_moderation ? 79 - AQ_CFG_INTERRUPT_MODERATION_RATE_DEF : 0U; 64 + cfg->itr = aq_itr; 65 + cfg->tx_itr = aq_itr_tx; 66 + cfg->rx_itr = aq_itr_rx; 80 67 81 68 cfg->is_rss = AQ_CFG_IS_RSS_DEF; 82 69 cfg->num_rss_queues = AQ_CFG_NUM_RSS_QUEUES_DEF; ··· 139 126 if (err) 140 127 return err; 141 128 142 - if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) 129 + if (self->link_status.mbps != self->aq_hw->aq_link_status.mbps) { 143 130 pr_info("%s: link change old %d new %d\n", 144 131 AQ_CFG_DRV_NAME, self->link_status.mbps, 145 132 self->aq_hw->aq_link_status.mbps); 133 + aq_nic_update_interrupt_moderation_settings(self); 134 + } 146 135 147 136 self->link_status = self->aq_hw->aq_link_status; 148 137 if (!netif_carrier_ok(self->ndev) && self->link_status.mbps) { ··· 179 164 if (err) 180 165 goto err_exit; 181 166 182 - self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, 183 - self->aq_nic_cfg.is_interrupt_moderation); 167 + if (self->aq_hw_ops.hw_update_stats) 168 + self->aq_hw_ops.hw_update_stats(self->aq_hw); 184 169 185 170 memset(&stats_rx, 0U, sizeof(struct aq_ring_stats_rx_s)); 186 171 memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); ··· 349 334 } 350 335 if (netif_running(ndev)) 351 336 netif_tx_disable(ndev); 337 + netif_carrier_off(self->ndev); 352 338 353 339 for (self->aq_vecs = 0; self->aq_vecs < self->aq_nic_cfg.vecs; 354 340 self->aq_vecs++) { ··· 437 421 if (err < 0) 438 422 goto err_exit; 439 423 440 - err = self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw, 441 - self->aq_nic_cfg.is_interrupt_moderation); 442 - if (err < 0) 424 + err = aq_nic_update_interrupt_moderation_settings(self); 425 + if (err) 443 426 goto err_exit; 444 427 setup_timer(&self->service_timer, &aq_nic_service_timer_cb, 445 428 (unsigned long)self); ··· 658 643 659 644 err_exit: 660 645 return err; 646 + } 647 + 648 + int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self) 649 + { 650 + return self->aq_hw_ops.hw_interrupt_moderation_set(self->aq_hw); 661 651 } 662 652 663 653 int aq_nic_set_packet_filter(struct aq_nic_s *self, unsigned int flags) ··· 919 899 unsigned int i = 0U; 920 900 921 901 netif_tx_disable(self->ndev); 902 + netif_carrier_off(self->ndev); 922 903 923 904 del_timer_sync(&self->service_timer); 924 905
+3 -1
drivers/net/ethernet/aquantia/atlantic/aq_nic.h
··· 40 40 u32 vecs; /* vecs==allocated irqs */ 41 41 u32 irq_type; 42 42 u32 itr; 43 + u16 rx_itr; 44 + u16 tx_itr; 43 45 u32 num_rss_queues; 44 46 u32 mtu; 45 47 u32 ucp_0x364; ··· 51 49 u16 is_mc_list_enabled; 52 50 u16 mc_list_count; 53 51 bool is_autoneg; 54 - bool is_interrupt_moderation; 55 52 bool is_polling; 56 53 bool is_rss; 57 54 bool is_lro; ··· 105 104 struct aq_nic_cfg_s *aq_nic_get_cfg(struct aq_nic_s *self); 106 105 u32 aq_nic_get_fw_version(struct aq_nic_s *self); 107 106 int aq_nic_change_pm_state(struct aq_nic_s *self, pm_message_t *pm_msg); 107 + int aq_nic_update_interrupt_moderation_settings(struct aq_nic_s *self); 108 108 109 109 #endif /* AQ_NIC_H */
+10 -4
drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
··· 85 85 int err = 0; 86 86 unsigned int bar = 0U; 87 87 unsigned int port = 0U; 88 + unsigned int numvecs = 0U; 88 89 89 90 err = pci_enable_device(self->pdev); 90 91 if (err < 0) ··· 143 142 } 144 143 } 145 144 146 - /*enable interrupts */ 145 + numvecs = min((u8)AQ_CFG_VECS_DEF, self->aq_hw_caps.msix_irqs); 146 + numvecs = min(numvecs, num_online_cpus()); 147 + 148 + /* enable interrupts */ 147 149 #if !AQ_CFG_FORCE_LEGACY_INT 148 - err = pci_alloc_irq_vectors(self->pdev, self->aq_hw_caps.msix_irqs, 149 - self->aq_hw_caps.msix_irqs, PCI_IRQ_MSIX); 150 + err = pci_alloc_irq_vectors(self->pdev, numvecs, numvecs, PCI_IRQ_MSIX); 150 151 151 152 if (err < 0) { 152 153 err = pci_alloc_irq_vectors(self->pdev, 1, 1, ··· 156 153 if (err < 0) 157 154 goto err_exit; 158 155 } 159 - #endif 156 + #endif /* AQ_CFG_FORCE_LEGACY_INT */ 160 157 161 158 /* net device init */ 162 159 for (port = 0; port < self->ports; ++port) { ··· 267 264 268 265 aq_nic_ndev_free(self->port[port]); 269 266 } 267 + 268 + if (self->mmio) 269 + iounmap(self->mmio); 270 270 271 271 kfree(self); 272 272
+3
drivers/net/ethernet/aquantia/atlantic/aq_vec.c
··· 373 373 memset(&stats_tx, 0U, sizeof(struct aq_ring_stats_tx_s)); 374 374 aq_vec_add_stats(self, &stats_rx, &stats_tx); 375 375 376 + /* This data should mimic aq_ethtool_queue_stat_names structure 377 + */ 376 378 data[count] += stats_rx.packets; 377 379 data[++count] += stats_tx.packets; 380 + data[++count] += stats_tx.queue_restarts; 378 381 data[++count] += stats_rx.jumbo_packets; 379 382 data[++count] += stats_rx.lro_packets; 380 383 data[++count] += stats_rx.errors;
+10 -11
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
··· 765 765 return err; 766 766 } 767 767 768 - static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self, 769 - bool itr_enabled) 768 + static int hw_atl_a0_hw_interrupt_moderation_set(struct aq_hw_s *self) 770 769 { 771 770 unsigned int i = 0U; 771 + u32 itr_rx; 772 772 773 - if (itr_enabled && self->aq_nic_cfg->itr) { 774 - if (self->aq_nic_cfg->itr != 0xFFFFU) { 773 + if (self->aq_nic_cfg->itr) { 774 + if (self->aq_nic_cfg->itr != AQ_CFG_INTERRUPT_MODERATION_AUTO) { 775 775 u32 itr_ = (self->aq_nic_cfg->itr >> 1); 776 776 777 777 itr_ = min(AQ_CFG_IRQ_MASK, itr_); 778 778 779 - PHAL_ATLANTIC_A0->itr_rx = 0x80000000U | 780 - (itr_ << 0x10); 779 + itr_rx = 0x80000000U | (itr_ << 0x10); 781 780 } else { 782 781 u32 n = 0xFFFFU & aq_hw_read_reg(self, 0x00002A00U); 783 782 784 783 if (n < self->aq_link_status.mbps) { 785 - PHAL_ATLANTIC_A0->itr_rx = 0U; 784 + itr_rx = 0U; 786 785 } else { 787 786 static unsigned int hw_timers_tbl_[] = { 788 787 0x01CU, /* 10Gbit */ ··· 796 797 hw_atl_utils_mbps_2_speed_index( 797 798 self->aq_link_status.mbps); 798 799 799 - PHAL_ATLANTIC_A0->itr_rx = 800 - 0x80000000U | 800 + itr_rx = 0x80000000U | 801 801 (hw_timers_tbl_[speed_index] << 0x10U); 802 802 } 803 803 ··· 804 806 aq_hw_write_reg(self, 0x00002A00U, 0x8D000000U); 805 807 } 806 808 } else { 807 - PHAL_ATLANTIC_A0->itr_rx = 0U; 809 + itr_rx = 0U; 808 810 } 809 811 810 812 for (i = HW_ATL_A0_RINGS_MAX; i--;) 811 - reg_irq_thr_set(self, PHAL_ATLANTIC_A0->itr_rx, i); 813 + reg_irq_thr_set(self, itr_rx, i); 812 814 813 815 return aq_hw_err_from_flags(self); 814 816 } ··· 883 885 .hw_rss_set = hw_atl_a0_hw_rss_set, 884 886 .hw_rss_hash_set = hw_atl_a0_hw_rss_hash_set, 885 887 .hw_get_regs = hw_atl_utils_hw_get_regs, 888 + .hw_update_stats = hw_atl_utils_update_stats, 886 889 .hw_get_hw_stats = hw_atl_utils_get_hw_stats, 887 890 .hw_get_fw_version = hw_atl_utils_get_fw_version, 888 891 };
+48 -39
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
··· 788 788 return err; 789 789 } 790 790 791 - static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self, 792 - bool itr_enabled) 791 + static int hw_atl_b0_hw_interrupt_moderation_set(struct aq_hw_s *self) 793 792 { 794 793 unsigned int i = 0U; 794 + u32 itr_tx = 2U; 795 + u32 itr_rx = 2U; 795 796 796 - if (itr_enabled && self->aq_nic_cfg->itr) { 797 + switch (self->aq_nic_cfg->itr) { 798 + case AQ_CFG_INTERRUPT_MODERATION_ON: 799 + case AQ_CFG_INTERRUPT_MODERATION_AUTO: 797 800 tdm_tx_desc_wr_wb_irq_en_set(self, 0U); 798 801 tdm_tdm_intr_moder_en_set(self, 1U); 799 802 rdm_rx_desc_wr_wb_irq_en_set(self, 0U); 800 803 rdm_rdm_intr_moder_en_set(self, 1U); 801 804 802 - PHAL_ATLANTIC_B0->itr_tx = 2U; 803 - PHAL_ATLANTIC_B0->itr_rx = 2U; 805 + if (self->aq_nic_cfg->itr == AQ_CFG_INTERRUPT_MODERATION_ON) { 806 + /* HW timers are in 2us units */ 807 + int tx_max_timer = self->aq_nic_cfg->tx_itr / 2; 808 + int tx_min_timer = tx_max_timer / 2; 804 809 805 - if (self->aq_nic_cfg->itr != 0xFFFFU) { 806 - unsigned int max_timer = self->aq_nic_cfg->itr / 2U; 807 - unsigned int min_timer = self->aq_nic_cfg->itr / 32U; 810 + int rx_max_timer = self->aq_nic_cfg->rx_itr / 2; 811 + int rx_min_timer = rx_max_timer / 2; 808 812 809 - max_timer = min(0x1FFU, max_timer); 810 - min_timer = min(0xFFU, min_timer); 813 + tx_max_timer = min(HW_ATL_INTR_MODER_MAX, tx_max_timer); 814 + tx_min_timer = min(HW_ATL_INTR_MODER_MIN, tx_min_timer); 815 + rx_max_timer = min(HW_ATL_INTR_MODER_MAX, rx_max_timer); 816 + rx_min_timer = min(HW_ATL_INTR_MODER_MIN, rx_min_timer); 811 817 812 - PHAL_ATLANTIC_B0->itr_tx |= min_timer << 0x8U; 813 - PHAL_ATLANTIC_B0->itr_tx |= max_timer << 0x10U; 814 - PHAL_ATLANTIC_B0->itr_rx |= min_timer << 0x8U; 815 - PHAL_ATLANTIC_B0->itr_rx |= max_timer << 0x10U; 818 + itr_tx |= tx_min_timer << 0x8U; 819 + itr_tx |= tx_max_timer << 0x10U; 820 + itr_rx |= rx_min_timer << 0x8U; 821 + itr_rx |= rx_max_timer << 0x10U; 816 822 } else { 817 823 static unsigned int hw_atl_b0_timers_table_tx_[][2] = { 818 - {0xffU, 0xffU}, /* 10Gbit */ 819 - {0xffU, 0x1ffU}, /* 5Gbit */ 820 - {0xffU, 0x1ffU}, /* 5Gbit 5GS */ 821 - {0xffU, 0x1ffU}, /* 2.5Gbit */ 822 - {0xffU, 0x1ffU}, /* 1Gbit */ 823 - {0xffU, 0x1ffU}, /* 100Mbit */ 824 + {0xfU, 0xffU}, /* 10Gbit */ 825 + {0xfU, 0x1ffU}, /* 5Gbit */ 826 + {0xfU, 0x1ffU}, /* 5Gbit 5GS */ 827 + {0xfU, 0x1ffU}, /* 2.5Gbit */ 828 + {0xfU, 0x1ffU}, /* 1Gbit */ 829 + {0xfU, 0x1ffU}, /* 100Mbit */ 824 830 }; 825 831 826 832 static unsigned int hw_atl_b0_timers_table_rx_[][2] = { ··· 842 836 hw_atl_utils_mbps_2_speed_index( 843 837 self->aq_link_status.mbps); 844 838 845 - PHAL_ATLANTIC_B0->itr_tx |= 846 - hw_atl_b0_timers_table_tx_[speed_index] 847 - [0] << 0x8U; /* set min timer value */ 848 - PHAL_ATLANTIC_B0->itr_tx |= 849 - hw_atl_b0_timers_table_tx_[speed_index] 850 - [1] << 0x10U; /* set max timer value */ 839 + /* Update user visible ITR settings */ 840 + self->aq_nic_cfg->tx_itr = hw_atl_b0_timers_table_tx_ 841 + [speed_index][1] * 2; 842 + self->aq_nic_cfg->rx_itr = hw_atl_b0_timers_table_rx_ 843 + [speed_index][1] * 2; 851 844 852 - PHAL_ATLANTIC_B0->itr_rx |= 853 - hw_atl_b0_timers_table_rx_[speed_index] 854 - [0] << 0x8U; /* set min timer value */ 855 - PHAL_ATLANTIC_B0->itr_rx |= 856 - hw_atl_b0_timers_table_rx_[speed_index] 857 - [1] << 0x10U; /* set max timer value */ 845 + itr_tx |= hw_atl_b0_timers_table_tx_ 846 + [speed_index][0] << 0x8U; 847 + itr_tx |= hw_atl_b0_timers_table_tx_ 848 + [speed_index][1] << 0x10U; 849 + 850 + itr_rx |= hw_atl_b0_timers_table_rx_ 851 + [speed_index][0] << 0x8U; 852 + itr_rx |= hw_atl_b0_timers_table_rx_ 853 + [speed_index][1] << 0x10U; 858 854 } 859 - } else { 855 + break; 856 + case AQ_CFG_INTERRUPT_MODERATION_OFF: 860 857 tdm_tx_desc_wr_wb_irq_en_set(self, 1U); 861 858 tdm_tdm_intr_moder_en_set(self, 0U); 862 859 rdm_rx_desc_wr_wb_irq_en_set(self, 1U); 863 860 rdm_rdm_intr_moder_en_set(self, 0U); 864 - PHAL_ATLANTIC_B0->itr_tx = 0U; 865 - PHAL_ATLANTIC_B0->itr_rx = 0U; 861 + itr_tx = 0U; 862 + itr_rx = 0U; 863 + break; 866 864 } 867 865 868 866 for (i = HW_ATL_B0_RINGS_MAX; i--;) { 869 - reg_tx_intr_moder_ctrl_set(self, 870 - PHAL_ATLANTIC_B0->itr_tx, i); 871 - reg_rx_intr_moder_ctrl_set(self, 872 - PHAL_ATLANTIC_B0->itr_rx, i); 867 + reg_tx_intr_moder_ctrl_set(self, itr_tx, i); 868 + reg_rx_intr_moder_ctrl_set(self, itr_rx, i); 873 869 } 874 870 875 871 return aq_hw_err_from_flags(self); ··· 947 939 .hw_rss_set = hw_atl_b0_hw_rss_set, 948 940 .hw_rss_hash_set = hw_atl_b0_hw_rss_hash_set, 949 941 .hw_get_regs = hw_atl_utils_hw_get_regs, 942 + .hw_update_stats = hw_atl_utils_update_stats, 950 943 .hw_get_hw_stats = hw_atl_utils_get_hw_stats, 951 944 .hw_get_fw_version = hw_atl_utils_get_fw_version, 952 945 };
+3
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0_internal.h
··· 139 139 140 140 #define HW_ATL_B0_FW_VER_EXPECTED 0x01050006U 141 141 142 + #define HW_ATL_INTR_MODER_MAX 0x1FF 143 + #define HW_ATL_INTR_MODER_MIN 0xFF 144 + 142 145 /* Hardware tx descriptor */ 143 146 struct __packed hw_atl_txd_s { 144 147 u64 buf_addr;
+55 -14
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.c
··· 255 255 return err; 256 256 } 257 257 258 + int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self, 259 + struct hw_aq_atl_utils_mbox_header *pmbox) 260 + { 261 + return hw_atl_utils_fw_downld_dwords(self, 262 + PHAL_ATLANTIC->mbox_addr, 263 + (u32 *)(void *)pmbox, 264 + sizeof(*pmbox) / sizeof(u32)); 265 + } 266 + 258 267 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self, 259 268 struct hw_aq_atl_utils_mbox *pmbox) 260 269 { ··· 275 266 sizeof(*pmbox) / sizeof(u32)); 276 267 if (err < 0) 277 268 goto err_exit; 278 - 279 - if (pmbox != &PHAL_ATLANTIC->mbox) 280 - memcpy(pmbox, &PHAL_ATLANTIC->mbox, sizeof(*pmbox)); 281 269 282 270 if (IS_CHIP_FEATURE(REVISION_A0)) { 283 271 unsigned int mtu = self->aq_nic_cfg ? ··· 305 299 { 306 300 int err = 0; 307 301 u32 transaction_id = 0; 302 + struct hw_aq_atl_utils_mbox_header mbox; 308 303 309 304 if (state == MPI_RESET) { 310 - hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox); 305 + hw_atl_utils_mpi_read_mbox(self, &mbox); 311 306 312 - transaction_id = PHAL_ATLANTIC->mbox.transaction_id; 307 + transaction_id = mbox.transaction_id; 313 308 314 309 AQ_HW_WAIT_FOR(transaction_id != 315 - (hw_atl_utils_mpi_read_stats 316 - (self, &PHAL_ATLANTIC->mbox), 317 - PHAL_ATLANTIC->mbox.transaction_id), 318 - 1000U, 100U); 310 + (hw_atl_utils_mpi_read_mbox(self, &mbox), 311 + mbox.transaction_id), 312 + 1000U, 100U); 319 313 if (err < 0) 320 314 goto err_exit; 321 315 } ··· 498 492 return 0; 499 493 } 500 494 495 + int hw_atl_utils_update_stats(struct aq_hw_s *self) 496 + { 497 + struct hw_atl_s *hw_self = PHAL_ATLANTIC; 498 + struct hw_aq_atl_utils_mbox mbox; 499 + 500 + if (!self->aq_link_status.mbps) 501 + return 0; 502 + 503 + hw_atl_utils_mpi_read_stats(self, &mbox); 504 + 505 + #define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \ 506 + mbox.stats._N_ - hw_self->last_stats._N_) 507 + 508 + AQ_SDELTA(uprc); 509 + AQ_SDELTA(mprc); 510 + AQ_SDELTA(bprc); 511 + AQ_SDELTA(erpt); 512 + 513 + AQ_SDELTA(uptc); 514 + AQ_SDELTA(mptc); 515 + AQ_SDELTA(bptc); 516 + AQ_SDELTA(erpr); 517 + 518 + AQ_SDELTA(ubrc); 519 + AQ_SDELTA(ubtc); 520 + AQ_SDELTA(mbrc); 521 + AQ_SDELTA(mbtc); 522 + AQ_SDELTA(bbrc); 523 + AQ_SDELTA(bbtc); 524 + AQ_SDELTA(dpc); 525 + 526 + #undef AQ_SDELTA 527 + 528 + memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats)); 529 + 530 + return 0; 531 + } 532 + 501 533 int hw_atl_utils_get_hw_stats(struct aq_hw_s *self, 502 534 u64 *data, unsigned int *p_count) 503 535 { 504 - struct hw_atl_stats_s *stats = NULL; 536 + struct hw_atl_s *hw_self = PHAL_ATLANTIC; 537 + struct hw_atl_stats_s *stats = &hw_self->curr_stats; 505 538 int i = 0; 506 - 507 - hw_atl_utils_mpi_read_stats(self, &PHAL_ATLANTIC->mbox); 508 - 509 - stats = &PHAL_ATLANTIC->mbox.stats; 510 539 511 540 data[i] = stats->uprc + stats->mprc + stats->bprc; 512 541 data[++i] = stats->uprc;
+13 -5
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_utils.h
··· 115 115 }; 116 116 }; 117 117 118 - struct __packed hw_aq_atl_utils_mbox { 118 + struct __packed hw_aq_atl_utils_mbox_header { 119 119 u32 version; 120 120 u32 transaction_id; 121 - int error; 121 + u32 error; 122 + }; 123 + 124 + struct __packed hw_aq_atl_utils_mbox { 125 + struct hw_aq_atl_utils_mbox_header header; 122 126 struct hw_atl_stats_s stats; 123 127 }; 124 128 125 129 struct __packed hw_atl_s { 126 130 struct aq_hw_s base; 127 - struct hw_aq_atl_utils_mbox mbox; 131 + struct hw_atl_stats_s last_stats; 132 + struct hw_atl_stats_s curr_stats; 128 133 u64 speed; 129 - u32 itr_tx; 130 - u32 itr_rx; 131 134 unsigned int chip_features; 132 135 u32 fw_ver_actual; 133 136 atomic_t dpc; ··· 173 170 174 171 void hw_atl_utils_hw_chip_features_init(struct aq_hw_s *self, u32 *p); 175 172 173 + int hw_atl_utils_mpi_read_mbox(struct aq_hw_s *self, 174 + struct hw_aq_atl_utils_mbox_header *pmbox); 175 + 176 176 void hw_atl_utils_mpi_read_stats(struct aq_hw_s *self, 177 177 struct hw_aq_atl_utils_mbox *pmbox); 178 178 ··· 204 198 int hw_atl_utils_hw_deinit(struct aq_hw_s *self); 205 199 206 200 int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version); 201 + 202 + int hw_atl_utils_update_stats(struct aq_hw_s *self); 207 203 208 204 int hw_atl_utils_get_hw_stats(struct aq_hw_s *self, 209 205 u64 *data,
+73 -26
drivers/net/ethernet/broadcom/bnxt/bnxt.c
··· 214 214 ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE, 215 215 }; 216 216 217 + static struct workqueue_struct *bnxt_pf_wq; 218 + 217 219 static bool bnxt_vf_pciid(enum board_idx idx) 218 220 { 219 221 return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF); ··· 1026 1024 return 0; 1027 1025 } 1028 1026 1027 + static void bnxt_queue_sp_work(struct bnxt *bp) 1028 + { 1029 + if (BNXT_PF(bp)) 1030 + queue_work(bnxt_pf_wq, &bp->sp_task); 1031 + else 1032 + schedule_work(&bp->sp_task); 1033 + } 1034 + 1035 + static void bnxt_cancel_sp_work(struct bnxt *bp) 1036 + { 1037 + if (BNXT_PF(bp)) 1038 + flush_workqueue(bnxt_pf_wq); 1039 + else 1040 + cancel_work_sync(&bp->sp_task); 1041 + } 1042 + 1029 1043 static void bnxt_sched_reset(struct bnxt *bp, struct bnxt_rx_ring_info *rxr) 1030 1044 { 1031 1045 if (!rxr->bnapi->in_reset) { 1032 1046 rxr->bnapi->in_reset = true; 1033 1047 set_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event); 1034 - schedule_work(&bp->sp_task); 1048 + bnxt_queue_sp_work(bp); 1035 1049 } 1036 1050 rxr->rx_next_cons = 0xffff; 1037 1051 } ··· 1735 1717 default: 1736 1718 goto async_event_process_exit; 1737 1719 } 1738 - schedule_work(&bp->sp_task); 1720 + bnxt_queue_sp_work(bp); 1739 1721 async_event_process_exit: 1740 1722 bnxt_ulp_async_events(bp, cmpl); 1741 1723 return 0; ··· 1769 1751 1770 1752 set_bit(vf_id - bp->pf.first_vf_id, bp->pf.vf_event_bmap); 1771 1753 set_bit(BNXT_HWRM_EXEC_FWD_REQ_SP_EVENT, &bp->sp_event); 1772 - schedule_work(&bp->sp_task); 1754 + bnxt_queue_sp_work(bp); 1773 1755 break; 1774 1756 1775 1757 case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT: ··· 3464 3446 int _hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) 3465 3447 { 3466 3448 return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, false); 3449 + } 3450 + 3451 + int _hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 msg_len, 3452 + int timeout) 3453 + { 3454 + return bnxt_hwrm_do_send_msg(bp, msg, msg_len, timeout, true); 3467 3455 } 3468 3456 3469 3457 int hwrm_send_message(struct bnxt *bp, void *msg, u32 msg_len, int timeout) ··· 6351 6327 } 6352 6328 6353 6329 if (link_re_init) { 6330 + mutex_lock(&bp->link_lock); 6354 6331 rc = bnxt_update_phy_setting(bp); 6332 + mutex_unlock(&bp->link_lock); 6355 6333 if (rc) 6356 6334 netdev_warn(bp->dev, "failed to update phy settings\n"); 6357 6335 } ··· 6673 6647 vnic->rx_mask = mask; 6674 6648 6675 6649 set_bit(BNXT_RX_MASK_SP_EVENT, &bp->sp_event); 6676 - schedule_work(&bp->sp_task); 6650 + bnxt_queue_sp_work(bp); 6677 6651 } 6678 6652 } 6679 6653 ··· 6946 6920 6947 6921 netdev_err(bp->dev, "TX timeout detected, starting reset task!\n"); 6948 6922 set_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event); 6949 - schedule_work(&bp->sp_task); 6923 + bnxt_queue_sp_work(bp); 6950 6924 } 6951 6925 6952 6926 #ifdef CONFIG_NET_POLL_CONTROLLER ··· 6978 6952 if (bp->link_info.link_up && (bp->flags & BNXT_FLAG_PORT_STATS) && 6979 6953 bp->stats_coal_ticks) { 6980 6954 set_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event); 6981 - schedule_work(&bp->sp_task); 6955 + bnxt_queue_sp_work(bp); 6982 6956 } 6983 6957 bnxt_restart_timer: 6984 6958 mod_timer(&bp->timer, jiffies + bp->current_interval); ··· 7051 7025 if (test_and_clear_bit(BNXT_PERIODIC_STATS_SP_EVENT, &bp->sp_event)) 7052 7026 bnxt_hwrm_port_qstats(bp); 7053 7027 7054 - /* These functions below will clear BNXT_STATE_IN_SP_TASK. They 7055 - * must be the last functions to be called before exiting. 7056 - */ 7057 7028 if (test_and_clear_bit(BNXT_LINK_CHNG_SP_EVENT, &bp->sp_event)) { 7058 - int rc = 0; 7029 + int rc; 7059 7030 7031 + mutex_lock(&bp->link_lock); 7060 7032 if (test_and_clear_bit(BNXT_LINK_SPEED_CHNG_SP_EVENT, 7061 7033 &bp->sp_event)) 7062 7034 bnxt_hwrm_phy_qcaps(bp); 7063 7035 7064 - bnxt_rtnl_lock_sp(bp); 7065 - if (test_bit(BNXT_STATE_OPEN, &bp->state)) 7066 - rc = bnxt_update_link(bp, true); 7067 - bnxt_rtnl_unlock_sp(bp); 7036 + rc = bnxt_update_link(bp, true); 7037 + mutex_unlock(&bp->link_lock); 7068 7038 if (rc) 7069 7039 netdev_err(bp->dev, "SP task can't update link (rc: %x)\n", 7070 7040 rc); 7071 7041 } 7072 7042 if (test_and_clear_bit(BNXT_HWRM_PORT_MODULE_SP_EVENT, &bp->sp_event)) { 7073 - bnxt_rtnl_lock_sp(bp); 7074 - if (test_bit(BNXT_STATE_OPEN, &bp->state)) 7075 - bnxt_get_port_module_status(bp); 7076 - bnxt_rtnl_unlock_sp(bp); 7043 + mutex_lock(&bp->link_lock); 7044 + bnxt_get_port_module_status(bp); 7045 + mutex_unlock(&bp->link_lock); 7077 7046 } 7047 + /* These functions below will clear BNXT_STATE_IN_SP_TASK. They 7048 + * must be the last functions to be called before exiting. 7049 + */ 7078 7050 if (test_and_clear_bit(BNXT_RESET_TASK_SP_EVENT, &bp->sp_event)) 7079 7051 bnxt_reset(bp, false); 7080 7052 ··· 7457 7433 spin_unlock_bh(&bp->ntp_fltr_lock); 7458 7434 7459 7435 set_bit(BNXT_RX_NTP_FLTR_SP_EVENT, &bp->sp_event); 7460 - schedule_work(&bp->sp_task); 7436 + bnxt_queue_sp_work(bp); 7461 7437 7462 7438 return new_fltr->sw_id; 7463 7439 ··· 7540 7516 if (bp->vxlan_port_cnt == 1) { 7541 7517 bp->vxlan_port = ti->port; 7542 7518 set_bit(BNXT_VXLAN_ADD_PORT_SP_EVENT, &bp->sp_event); 7543 - schedule_work(&bp->sp_task); 7519 + bnxt_queue_sp_work(bp); 7544 7520 } 7545 7521 break; 7546 7522 case UDP_TUNNEL_TYPE_GENEVE: ··· 7557 7533 return; 7558 7534 } 7559 7535 7560 - schedule_work(&bp->sp_task); 7536 + bnxt_queue_sp_work(bp); 7561 7537 } 7562 7538 7563 7539 static void bnxt_udp_tunnel_del(struct net_device *dev, ··· 7596 7572 return; 7597 7573 } 7598 7574 7599 - schedule_work(&bp->sp_task); 7575 + bnxt_queue_sp_work(bp); 7600 7576 } 7601 7577 7602 7578 static int bnxt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq, ··· 7744 7720 pci_disable_pcie_error_reporting(pdev); 7745 7721 unregister_netdev(dev); 7746 7722 bnxt_shutdown_tc(bp); 7747 - cancel_work_sync(&bp->sp_task); 7723 + bnxt_cancel_sp_work(bp); 7748 7724 bp->sp_event = 0; 7749 7725 7750 7726 bnxt_clear_int_mode(bp); ··· 7772 7748 rc); 7773 7749 return rc; 7774 7750 } 7751 + mutex_init(&bp->link_lock); 7775 7752 7776 7753 rc = bnxt_update_link(bp, false); 7777 7754 if (rc) { ··· 7971 7946 enum pcie_link_width width = PCIE_LNK_WIDTH_UNKNOWN; 7972 7947 enum pci_bus_speed speed = PCI_SPEED_UNKNOWN; 7973 7948 7974 - if (pcie_get_minimum_link(bp->pdev, &speed, &width) || 7949 + if (pcie_get_minimum_link(pci_physfn(bp->pdev), &speed, &width) || 7975 7950 speed == PCI_SPEED_UNKNOWN || width == PCIE_LNK_WIDTH_UNKNOWN) 7976 7951 netdev_info(bp->dev, "Failed to determine PCIe Link Info\n"); 7977 7952 else ··· 8163 8138 else 8164 8139 device_set_wakeup_capable(&pdev->dev, false); 8165 8140 8166 - if (BNXT_PF(bp)) 8141 + if (BNXT_PF(bp)) { 8142 + if (!bnxt_pf_wq) { 8143 + bnxt_pf_wq = 8144 + create_singlethread_workqueue("bnxt_pf_wq"); 8145 + if (!bnxt_pf_wq) { 8146 + dev_err(&pdev->dev, "Unable to create workqueue.\n"); 8147 + goto init_err_pci_clean; 8148 + } 8149 + } 8167 8150 bnxt_init_tc(bp); 8151 + } 8168 8152 8169 8153 rc = register_netdev(dev); 8170 8154 if (rc) ··· 8409 8375 #endif 8410 8376 }; 8411 8377 8412 - module_pci_driver(bnxt_pci_driver); 8378 + static int __init bnxt_init(void) 8379 + { 8380 + return pci_register_driver(&bnxt_pci_driver); 8381 + } 8382 + 8383 + static void __exit bnxt_exit(void) 8384 + { 8385 + pci_unregister_driver(&bnxt_pci_driver); 8386 + if (bnxt_pf_wq) 8387 + destroy_workqueue(bnxt_pf_wq); 8388 + } 8389 + 8390 + module_init(bnxt_init); 8391 + module_exit(bnxt_exit);
+5
drivers/net/ethernet/broadcom/bnxt/bnxt.h
··· 1290 1290 unsigned long *ntp_fltr_bmap; 1291 1291 int ntp_fltr_count; 1292 1292 1293 + /* To protect link related settings during link changes and 1294 + * ethtool settings changes. 1295 + */ 1296 + struct mutex link_lock; 1293 1297 struct bnxt_link_info link_info; 1294 1298 struct ethtool_eee eee; 1295 1299 u32 lpi_tmr_lo; ··· 1362 1358 int bnxt_set_rx_skb_mode(struct bnxt *bp, bool page_mode); 1363 1359 void bnxt_hwrm_cmd_hdr_init(struct bnxt *, void *, u16, u16, u16); 1364 1360 int _hwrm_send_message(struct bnxt *, void *, u32, int); 1361 + int _hwrm_send_message_silent(struct bnxt *bp, void *msg, u32 len, int timeout); 1365 1362 int hwrm_send_message(struct bnxt *, void *, u32, int); 1366 1363 int hwrm_send_message_silent(struct bnxt *, void *, u32, int); 1367 1364 int bnxt_hwrm_func_rgtr_async_events(struct bnxt *bp, unsigned long *bmap,
+18 -5
drivers/net/ethernet/broadcom/bnxt/bnxt_dcb.c
··· 50 50 51 51 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PRI2COS_QCFG, -1, -1); 52 52 req.flags = cpu_to_le32(QUEUE_PRI2COS_QCFG_REQ_FLAGS_IVLAN); 53 - rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 53 + 54 + mutex_lock(&bp->hwrm_cmd_lock); 55 + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 54 56 if (!rc) { 55 57 u8 *pri2cos = &resp->pri0_cos_queue_id; 56 58 int i, j; ··· 68 66 } 69 67 } 70 68 } 69 + mutex_unlock(&bp->hwrm_cmd_lock); 71 70 return rc; 72 71 } 73 72 ··· 122 119 int rc, i; 123 120 124 121 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_COS2BW_QCFG, -1, -1); 125 - rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 126 - if (rc) 122 + 123 + mutex_lock(&bp->hwrm_cmd_lock); 124 + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 125 + if (rc) { 126 + mutex_unlock(&bp->hwrm_cmd_lock); 127 127 return rc; 128 + } 128 129 129 130 data = &resp->queue_id0 + offsetof(struct bnxt_cos2bw_cfg, queue_id); 130 131 for (i = 0; i < bp->max_tc; i++, data += sizeof(cos2bw) - 4) { ··· 150 143 } 151 144 } 152 145 } 146 + mutex_unlock(&bp->hwrm_cmd_lock); 153 147 return 0; 154 148 } 155 149 ··· 248 240 int rc; 249 241 250 242 bnxt_hwrm_cmd_hdr_init(bp, &req, HWRM_QUEUE_PFCENABLE_QCFG, -1, -1); 251 - rc = hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 252 - if (rc) 243 + 244 + mutex_lock(&bp->hwrm_cmd_lock); 245 + rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 246 + if (rc) { 247 + mutex_unlock(&bp->hwrm_cmd_lock); 253 248 return rc; 249 + } 254 250 255 251 pri_mask = le32_to_cpu(resp->flags); 256 252 pfc->pfc_en = pri_mask; 253 + mutex_unlock(&bp->hwrm_cmd_lock); 257 254 return 0; 258 255 } 259 256
+7 -1
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
··· 1052 1052 u32 ethtool_speed; 1053 1053 1054 1054 ethtool_link_ksettings_zero_link_mode(lk_ksettings, supported); 1055 + mutex_lock(&bp->link_lock); 1055 1056 bnxt_fw_to_ethtool_support_spds(link_info, lk_ksettings); 1056 1057 1057 1058 ethtool_link_ksettings_zero_link_mode(lk_ksettings, advertising); ··· 1100 1099 base->port = PORT_FIBRE; 1101 1100 } 1102 1101 base->phy_address = link_info->phy_addr; 1102 + mutex_unlock(&bp->link_lock); 1103 1103 1104 1104 return 0; 1105 1105 } ··· 1192 1190 if (!BNXT_SINGLE_PF(bp)) 1193 1191 return -EOPNOTSUPP; 1194 1192 1193 + mutex_lock(&bp->link_lock); 1195 1194 if (base->autoneg == AUTONEG_ENABLE) { 1196 1195 BNXT_ETHTOOL_TO_FW_SPDS(fw_advertising, lk_ksettings, 1197 1196 advertising); ··· 1237 1234 rc = bnxt_hwrm_set_link_setting(bp, set_pause, false); 1238 1235 1239 1236 set_setting_exit: 1237 + mutex_unlock(&bp->link_lock); 1240 1238 return rc; 1241 1239 } 1242 1240 ··· 1809 1805 req.dir_ordinal = cpu_to_le16(ordinal); 1810 1806 req.dir_ext = cpu_to_le16(ext); 1811 1807 req.opt_ordinal = NVM_FIND_DIR_ENTRY_REQ_OPT_ORDINAL_EQ; 1812 - rc = hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 1808 + mutex_lock(&bp->hwrm_cmd_lock); 1809 + rc = _hwrm_send_message_silent(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); 1813 1810 if (rc == 0) { 1814 1811 if (index) 1815 1812 *index = le16_to_cpu(output->dir_idx); ··· 1819 1814 if (data_length) 1820 1815 *data_length = le32_to_cpu(output->dir_data_length); 1821 1816 } 1817 + mutex_unlock(&bp->hwrm_cmd_lock); 1822 1818 return rc; 1823 1819 } 1824 1820
+9 -2
drivers/net/ethernet/broadcom/bnxt/bnxt_sriov.c
··· 502 502 int rc = 0, vfs_supported; 503 503 int min_rx_rings, min_tx_rings, min_rss_ctxs; 504 504 int tx_ok = 0, rx_ok = 0, rss_ok = 0; 505 + int avail_cp, avail_stat; 505 506 506 507 /* Check if we can enable requested num of vf's. At a mininum 507 508 * we require 1 RX 1 TX rings for each VF. In this minimum conf 508 509 * features like TPA will not be available. 509 510 */ 510 511 vfs_supported = *num_vfs; 512 + 513 + avail_cp = bp->pf.max_cp_rings - bp->cp_nr_rings; 514 + avail_stat = bp->pf.max_stat_ctxs - bp->num_stat_ctxs; 515 + avail_cp = min_t(int, avail_cp, avail_stat); 511 516 512 517 while (vfs_supported) { 513 518 min_rx_rings = vfs_supported; ··· 528 523 min_rx_rings) 529 524 rx_ok = 1; 530 525 } 531 - if (bp->pf.max_vnics - bp->nr_vnics < min_rx_rings) 526 + if (bp->pf.max_vnics - bp->nr_vnics < min_rx_rings || 527 + avail_cp < min_rx_rings) 532 528 rx_ok = 0; 533 529 534 - if (bp->pf.max_tx_rings - bp->tx_nr_rings >= min_tx_rings) 530 + if (bp->pf.max_tx_rings - bp->tx_nr_rings >= min_tx_rings && 531 + avail_cp >= min_tx_rings) 535 532 tx_ok = 1; 536 533 537 534 if (bp->pf.max_rsscos_ctxs - bp->rsscos_nr_ctxs >= min_rss_ctxs)
+1 -1
drivers/net/ethernet/cavium/liquidio/lio_main.c
··· 1847 1847 struct lio *lio = container_of(ptp, struct lio, ptp_info); 1848 1848 struct octeon_device *oct = (struct octeon_device *)lio->oct_dev; 1849 1849 1850 - ns = timespec_to_ns(ts); 1850 + ns = timespec64_to_ns(ts); 1851 1851 1852 1852 spin_lock_irqsave(&lio->ptp_lock, flags); 1853 1853 lio_pci_writeq(oct, ns, CN6XXX_MIO_PTP_CLOCK_HI);
+8 -8
drivers/net/ethernet/ibm/ibmvnic.c
··· 1093 1093 * places them in a descriptor array, scrq_arr 1094 1094 */ 1095 1095 1096 - static void create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len, 1097 - union sub_crq *scrq_arr) 1096 + static int create_hdr_descs(u8 hdr_field, u8 *hdr_data, int len, int *hdr_len, 1097 + union sub_crq *scrq_arr) 1098 1098 { 1099 1099 union sub_crq hdr_desc; 1100 1100 int tmp_len = len; 1101 + int num_descs = 0; 1101 1102 u8 *data, *cur; 1102 1103 int tmp; 1103 1104 ··· 1127 1126 tmp_len -= tmp; 1128 1127 *scrq_arr = hdr_desc; 1129 1128 scrq_arr++; 1129 + num_descs++; 1130 1130 } 1131 + 1132 + return num_descs; 1131 1133 } 1132 1134 1133 1135 /** ··· 1148 1144 int *num_entries, u8 hdr_field) 1149 1145 { 1150 1146 int hdr_len[3] = {0, 0, 0}; 1151 - int tot_len, len; 1147 + int tot_len; 1152 1148 u8 *hdr_data = txbuff->hdr_data; 1153 1149 1154 1150 tot_len = build_hdr_data(hdr_field, txbuff->skb, hdr_len, 1155 1151 txbuff->hdr_data); 1156 - len = tot_len; 1157 - len -= 24; 1158 - if (len > 0) 1159 - num_entries += len % 29 ? len / 29 + 1 : len / 29; 1160 - create_hdr_descs(hdr_field, hdr_data, tot_len, hdr_len, 1152 + *num_entries += create_hdr_descs(hdr_field, hdr_data, tot_len, hdr_len, 1161 1153 txbuff->indir_arr + 1); 1162 1154 } 1163 1155
+1 -1
drivers/net/ethernet/intel/i40e/i40e_nvm.c
··· 298 298 } 299 299 300 300 /** 301 - * __i40e_read_nvm_word - Reads nvm word, assumes called does the locking 301 + * __i40e_read_nvm_word - Reads nvm word, assumes caller does the locking 302 302 * @hw: pointer to the HW structure 303 303 * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF) 304 304 * @data: word read from the Shadow RAM
+36 -27
drivers/net/ethernet/intel/i40e/i40e_txrx.c
··· 1038 1038 } 1039 1039 1040 1040 /** 1041 + * i40e_reuse_rx_page - page flip buffer and store it back on the ring 1042 + * @rx_ring: rx descriptor ring to store buffers on 1043 + * @old_buff: donor buffer to have page reused 1044 + * 1045 + * Synchronizes page for reuse by the adapter 1046 + **/ 1047 + static void i40e_reuse_rx_page(struct i40e_ring *rx_ring, 1048 + struct i40e_rx_buffer *old_buff) 1049 + { 1050 + struct i40e_rx_buffer *new_buff; 1051 + u16 nta = rx_ring->next_to_alloc; 1052 + 1053 + new_buff = &rx_ring->rx_bi[nta]; 1054 + 1055 + /* update, and store next to alloc */ 1056 + nta++; 1057 + rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; 1058 + 1059 + /* transfer page from old buffer to new buffer */ 1060 + new_buff->dma = old_buff->dma; 1061 + new_buff->page = old_buff->page; 1062 + new_buff->page_offset = old_buff->page_offset; 1063 + new_buff->pagecnt_bias = old_buff->pagecnt_bias; 1064 + } 1065 + 1066 + /** 1041 1067 * i40e_rx_is_programming_status - check for programming status descriptor 1042 1068 * @qw: qword representing status_error_len in CPU ordering 1043 1069 * ··· 1097 1071 union i40e_rx_desc *rx_desc, 1098 1072 u64 qw) 1099 1073 { 1100 - u32 ntc = rx_ring->next_to_clean + 1; 1074 + struct i40e_rx_buffer *rx_buffer; 1075 + u32 ntc = rx_ring->next_to_clean; 1101 1076 u8 id; 1102 1077 1103 1078 /* fetch, update, and store next to clean */ 1079 + rx_buffer = &rx_ring->rx_bi[ntc++]; 1104 1080 ntc = (ntc < rx_ring->count) ? ntc : 0; 1105 1081 rx_ring->next_to_clean = ntc; 1106 1082 1107 1083 prefetch(I40E_RX_DESC(rx_ring, ntc)); 1084 + 1085 + /* place unused page back on the ring */ 1086 + i40e_reuse_rx_page(rx_ring, rx_buffer); 1087 + rx_ring->rx_stats.page_reuse_count++; 1088 + 1089 + /* clear contents of buffer_info */ 1090 + rx_buffer->page = NULL; 1108 1091 1109 1092 id = (qw & I40E_RX_PROG_STATUS_DESC_QW1_PROGID_MASK) >> 1110 1093 I40E_RX_PROG_STATUS_DESC_QW1_PROGID_SHIFT; ··· 1671 1636 return true; 1672 1637 1673 1638 return false; 1674 - } 1675 - 1676 - /** 1677 - * i40e_reuse_rx_page - page flip buffer and store it back on the ring 1678 - * @rx_ring: rx descriptor ring to store buffers on 1679 - * @old_buff: donor buffer to have page reused 1680 - * 1681 - * Synchronizes page for reuse by the adapter 1682 - **/ 1683 - static void i40e_reuse_rx_page(struct i40e_ring *rx_ring, 1684 - struct i40e_rx_buffer *old_buff) 1685 - { 1686 - struct i40e_rx_buffer *new_buff; 1687 - u16 nta = rx_ring->next_to_alloc; 1688 - 1689 - new_buff = &rx_ring->rx_bi[nta]; 1690 - 1691 - /* update, and store next to alloc */ 1692 - nta++; 1693 - rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0; 1694 - 1695 - /* transfer page from old buffer to new buffer */ 1696 - new_buff->dma = old_buff->dma; 1697 - new_buff->page = old_buff->page; 1698 - new_buff->page_offset = old_buff->page_offset; 1699 - new_buff->pagecnt_bias = old_buff->pagecnt_bias; 1700 1639 } 1701 1640 1702 1641 /**
+10 -1
drivers/net/ethernet/mellanox/mlxsw/core.c
··· 96 96 const struct mlxsw_bus *bus; 97 97 void *bus_priv; 98 98 const struct mlxsw_bus_info *bus_info; 99 + struct workqueue_struct *emad_wq; 99 100 struct list_head rx_listener_list; 100 101 struct list_head event_listener_list; 101 102 struct { ··· 466 465 { 467 466 unsigned long timeout = msecs_to_jiffies(MLXSW_EMAD_TIMEOUT_MS); 468 467 469 - mlxsw_core_schedule_dw(&trans->timeout_dw, timeout); 468 + queue_delayed_work(trans->core->emad_wq, &trans->timeout_dw, timeout); 470 469 } 471 470 472 471 static int mlxsw_emad_transmit(struct mlxsw_core *mlxsw_core, ··· 588 587 589 588 static int mlxsw_emad_init(struct mlxsw_core *mlxsw_core) 590 589 { 590 + struct workqueue_struct *emad_wq; 591 591 u64 tid; 592 592 int err; 593 593 594 594 if (!(mlxsw_core->bus->features & MLXSW_BUS_F_TXRX)) 595 595 return 0; 596 + 597 + emad_wq = alloc_workqueue("mlxsw_core_emad", WQ_MEM_RECLAIM, 0); 598 + if (!emad_wq) 599 + return -ENOMEM; 600 + mlxsw_core->emad_wq = emad_wq; 596 601 597 602 /* Set the upper 32 bits of the transaction ID field to a random 598 603 * number. This allows us to discard EMADs addressed to other ··· 626 619 err_emad_trap_set: 627 620 mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, 628 621 mlxsw_core); 622 + destroy_workqueue(mlxsw_core->emad_wq); 629 623 return err; 630 624 } 631 625 ··· 639 631 mlxsw_core->emad.use_emad = false; 640 632 mlxsw_core_trap_unregister(mlxsw_core, &mlxsw_emad_rx_listener, 641 633 mlxsw_core); 634 + destroy_workqueue(mlxsw_core->emad_wq); 642 635 } 643 636 644 637 static struct sk_buff *mlxsw_emad_alloc(const struct mlxsw_core *mlxsw_core,
+31
drivers/net/ethernet/mellanox/mlxsw/reg.h
··· 6401 6401 mlxsw_reg_mgpc_opcode_set(payload, opcode); 6402 6402 } 6403 6403 6404 + /* TIGCR - Tunneling IPinIP General Configuration Register 6405 + * ------------------------------------------------------- 6406 + * The TIGCR register is used for setting up the IPinIP Tunnel configuration. 6407 + */ 6408 + #define MLXSW_REG_TIGCR_ID 0xA801 6409 + #define MLXSW_REG_TIGCR_LEN 0x10 6410 + 6411 + MLXSW_REG_DEFINE(tigcr, MLXSW_REG_TIGCR_ID, MLXSW_REG_TIGCR_LEN); 6412 + 6413 + /* reg_tigcr_ipip_ttlc 6414 + * For IPinIP Tunnel encapsulation: whether to copy the ttl from the packet 6415 + * header. 6416 + * Access: RW 6417 + */ 6418 + MLXSW_ITEM32(reg, tigcr, ttlc, 0x04, 8, 1); 6419 + 6420 + /* reg_tigcr_ipip_ttl_uc 6421 + * The TTL for IPinIP Tunnel encapsulation of unicast packets if 6422 + * reg_tigcr_ipip_ttlc is unset. 6423 + * Access: RW 6424 + */ 6425 + MLXSW_ITEM32(reg, tigcr, ttl_uc, 0x04, 0, 8); 6426 + 6427 + static inline void mlxsw_reg_tigcr_pack(char *payload, bool ttlc, u8 ttl_uc) 6428 + { 6429 + MLXSW_REG_ZERO(tigcr, payload); 6430 + mlxsw_reg_tigcr_ttlc_set(payload, ttlc); 6431 + mlxsw_reg_tigcr_ttl_uc_set(payload, ttl_uc); 6432 + } 6433 + 6404 6434 /* SBPR - Shared Buffer Pools Register 6405 6435 * ----------------------------------- 6406 6436 * The SBPR configures and retrieves the shared buffer pools and configuration. ··· 6911 6881 MLXSW_REG(mcc), 6912 6882 MLXSW_REG(mcda), 6913 6883 MLXSW_REG(mgpc), 6884 + MLXSW_REG(tigcr), 6914 6885 MLXSW_REG(sbpr), 6915 6886 MLXSW_REG(sbcm), 6916 6887 MLXSW_REG(sbpm),
+10 -1
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
··· 5896 5896 kfree(mlxsw_sp->router->rifs); 5897 5897 } 5898 5898 5899 + static int 5900 + mlxsw_sp_ipip_config_tigcr(struct mlxsw_sp *mlxsw_sp) 5901 + { 5902 + char tigcr_pl[MLXSW_REG_TIGCR_LEN]; 5903 + 5904 + mlxsw_reg_tigcr_pack(tigcr_pl, true, 0); 5905 + return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tigcr), tigcr_pl); 5906 + } 5907 + 5899 5908 static int mlxsw_sp_ipips_init(struct mlxsw_sp *mlxsw_sp) 5900 5909 { 5901 5910 mlxsw_sp->router->ipip_ops_arr = mlxsw_sp_ipip_ops_arr; 5902 5911 INIT_LIST_HEAD(&mlxsw_sp->router->ipip_list); 5903 - return 0; 5912 + return mlxsw_sp_ipip_config_tigcr(mlxsw_sp); 5904 5913 } 5905 5914 5906 5915 static void mlxsw_sp_ipips_fini(struct mlxsw_sp *mlxsw_sp)
+14 -6
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
··· 1180 1180 { 1181 1181 void *frag; 1182 1182 1183 - if (!dp->xdp_prog) 1183 + if (!dp->xdp_prog) { 1184 1184 frag = netdev_alloc_frag(dp->fl_bufsz); 1185 - else 1186 - frag = page_address(alloc_page(GFP_KERNEL | __GFP_COLD)); 1185 + } else { 1186 + struct page *page; 1187 + 1188 + page = alloc_page(GFP_KERNEL | __GFP_COLD); 1189 + frag = page ? page_address(page) : NULL; 1190 + } 1187 1191 if (!frag) { 1188 1192 nn_dp_warn(dp, "Failed to alloc receive page frag\n"); 1189 1193 return NULL; ··· 1207 1203 { 1208 1204 void *frag; 1209 1205 1210 - if (!dp->xdp_prog) 1206 + if (!dp->xdp_prog) { 1211 1207 frag = napi_alloc_frag(dp->fl_bufsz); 1212 - else 1213 - frag = page_address(alloc_page(GFP_ATOMIC | __GFP_COLD)); 1208 + } else { 1209 + struct page *page; 1210 + 1211 + page = alloc_page(GFP_ATOMIC | __GFP_COLD); 1212 + frag = page ? page_address(page) : NULL; 1213 + } 1214 1214 if (!frag) { 1215 1215 nn_dp_warn(dp, "Failed to alloc receive page frag\n"); 1216 1216 return NULL;
+5 -3
drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
··· 464 464 465 465 do { 466 466 start = u64_stats_fetch_begin(&nn->r_vecs[i].rx_sync); 467 - *data++ = nn->r_vecs[i].rx_pkts; 467 + data[0] = nn->r_vecs[i].rx_pkts; 468 468 tmp[0] = nn->r_vecs[i].hw_csum_rx_ok; 469 469 tmp[1] = nn->r_vecs[i].hw_csum_rx_inner_ok; 470 470 tmp[2] = nn->r_vecs[i].hw_csum_rx_error; ··· 472 472 473 473 do { 474 474 start = u64_stats_fetch_begin(&nn->r_vecs[i].tx_sync); 475 - *data++ = nn->r_vecs[i].tx_pkts; 476 - *data++ = nn->r_vecs[i].tx_busy; 475 + data[1] = nn->r_vecs[i].tx_pkts; 476 + data[2] = nn->r_vecs[i].tx_busy; 477 477 tmp[3] = nn->r_vecs[i].hw_csum_tx; 478 478 tmp[4] = nn->r_vecs[i].hw_csum_tx_inner; 479 479 tmp[5] = nn->r_vecs[i].tx_gather; 480 480 tmp[6] = nn->r_vecs[i].tx_lso; 481 481 } while (u64_stats_fetch_retry(&nn->r_vecs[i].tx_sync, start)); 482 + 483 + data += 3; 482 484 483 485 for (j = 0; j < NN_ET_RVEC_GATHER_STATS; j++) 484 486 gathered_stats[j] += tmp[j];
-2
drivers/net/ethernet/realtek/r8169.c
··· 8491 8491 rtl8168_driver_start(tp); 8492 8492 } 8493 8493 8494 - device_set_wakeup_enable(&pdev->dev, tp->features & RTL_FEATURE_WOL); 8495 - 8496 8494 if (pci_dev_run_wake(pdev)) 8497 8495 pm_runtime_put_noidle(&pdev->dev); 8498 8496
+1 -1
drivers/net/ethernet/stmicro/stmmac/dwmac4_descs.c
··· 275 275 goto exit; 276 276 i++; 277 277 278 - } while ((ret == 1) || (i < 10)); 278 + } while ((ret == 1) && (i < 10)); 279 279 280 280 if (i == 10) 281 281 ret = -EBUSY;
+1 -1
drivers/net/ethernet/stmicro/stmmac/dwmac_lib.c
··· 34 34 35 35 err = readl_poll_timeout(ioaddr + DMA_BUS_MODE, value, 36 36 !(value & DMA_BUS_MODE_SFT_RESET), 37 - 100000, 10000); 37 + 10000, 100000); 38 38 if (err) 39 39 return -EBUSY; 40 40
+9 -8
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 473 473 struct dma_desc *np, struct sk_buff *skb) 474 474 { 475 475 struct skb_shared_hwtstamps *shhwtstamp = NULL; 476 + struct dma_desc *desc = p; 476 477 u64 ns; 477 478 478 479 if (!priv->hwts_rx_en) 479 480 return; 481 + /* For GMAC4, the valid timestamp is from CTX next desc. */ 482 + if (priv->plat->has_gmac4) 483 + desc = np; 480 484 481 485 /* Check if timestamp is available */ 482 - if (priv->hw->desc->get_rx_timestamp_status(p, priv->adv_ts)) { 483 - /* For GMAC4, the valid timestamp is from CTX next desc. */ 484 - if (priv->plat->has_gmac4) 485 - ns = priv->hw->desc->get_timestamp(np, priv->adv_ts); 486 - else 487 - ns = priv->hw->desc->get_timestamp(p, priv->adv_ts); 488 - 486 + if (priv->hw->desc->get_rx_timestamp_status(desc, priv->adv_ts)) { 487 + ns = priv->hw->desc->get_timestamp(desc, priv->adv_ts); 489 488 netdev_dbg(priv->dev, "get valid RX hw timestamp %llu\n", ns); 490 489 shhwtstamp = skb_hwtstamps(skb); 491 490 memset(shhwtstamp, 0, sizeof(struct skb_shared_hwtstamps)); ··· 1799 1800 { 1800 1801 struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue]; 1801 1802 unsigned int bytes_compl = 0, pkts_compl = 0; 1802 - unsigned int entry = tx_q->dirty_tx; 1803 + unsigned int entry; 1803 1804 1804 1805 netif_tx_lock(priv->dev); 1805 1806 1806 1807 priv->xstats.tx_clean++; 1807 1808 1809 + entry = tx_q->dirty_tx; 1808 1810 while (entry != tx_q->cur_tx) { 1809 1811 struct sk_buff *skb = tx_q->tx_skbuff[entry]; 1810 1812 struct dma_desc *p; ··· 3333 3333 * them in stmmac_rx_refill() function so that 3334 3334 * device can reuse it. 3335 3335 */ 3336 + dev_kfree_skb_any(rx_q->rx_skbuff[entry]); 3336 3337 rx_q->rx_skbuff[entry] = NULL; 3337 3338 dma_unmap_single(priv->device, 3338 3339 rx_q->rx_skbuff_dma[entry],
-6
drivers/net/geneve.c
··· 113 113 114 114 static bool eq_tun_id_and_vni(u8 *tun_id, u8 *vni) 115 115 { 116 - #ifdef __BIG_ENDIAN 117 - return (vni[0] == tun_id[2]) && 118 - (vni[1] == tun_id[1]) && 119 - (vni[2] == tun_id[0]); 120 - #else 121 116 return !memcmp(vni, &tun_id[5], 3); 122 - #endif 123 117 } 124 118 125 119 static sa_family_t geneve_get_sk_family(struct geneve_sock *gs)
+2
drivers/net/macsec.c
··· 742 742 sg_init_table(sg, ret); 743 743 ret = skb_to_sgvec(skb, sg, 0, skb->len); 744 744 if (unlikely(ret < 0)) { 745 + aead_request_free(req); 745 746 macsec_txsa_put(tx_sa); 746 747 kfree_skb(skb); 747 748 return ERR_PTR(ret); ··· 955 954 sg_init_table(sg, ret); 956 955 ret = skb_to_sgvec(skb, sg, 0, skb->len); 957 956 if (unlikely(ret < 0)) { 957 + aead_request_free(req); 958 958 kfree_skb(skb); 959 959 return ERR_PTR(ret); 960 960 }
+3
drivers/net/tun.c
··· 2027 2027 2028 2028 if (!dev) 2029 2029 return -ENOMEM; 2030 + err = dev_get_valid_name(net, dev, name); 2031 + if (err) 2032 + goto err_free_dev; 2030 2033 2031 2034 dev_net_set(dev, net); 2032 2035 dev->rtnl_link_ops = &tun_link_ops;
+1 -1
drivers/net/wimax/i2400m/fw.c
··· 652 652 struct device *dev = i2400m_dev(i2400m); 653 653 struct { 654 654 struct i2400m_bootrom_header cmd; 655 - u8 cmd_payload[chunk_len]; 655 + u8 cmd_payload[]; 656 656 } __packed *buf; 657 657 struct i2400m_bootrom_header ack; 658 658
+2 -1
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c
··· 429 429 if (code != BRCMF_E_IF && !fweh->evt_handler[code]) 430 430 return; 431 431 432 - if (datalen > BRCMF_DCMD_MAXLEN) 432 + if (datalen > BRCMF_DCMD_MAXLEN || 433 + datalen + sizeof(*event_packet) > packet_len) 433 434 return; 434 435 435 436 if (in_interrupt())
+97 -100
drivers/net/wireless/broadcom/brcm80211/brcmsmac/phy/phy_n.c
··· 14764 14764 } 14765 14765 14766 14766 static void 14767 - wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, u8 *events, u8 *dlys, 14768 - u8 len) 14767 + wlc_phy_set_rfseq_nphy(struct brcms_phy *pi, u8 cmd, const u8 *events, 14768 + const u8 *dlys, u8 len) 14769 14769 { 14770 14770 u32 t1_offset, t2_offset; 14771 14771 u8 ctr; ··· 15240 15240 static void wlc_phy_workarounds_nphy_gainctrl_2057_rev6(struct brcms_phy *pi) 15241 15241 { 15242 15242 u16 currband; 15243 - s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; 15244 - s8 *lna1_gain_db = NULL; 15245 - s8 *lna1_gain_db_2 = NULL; 15246 - s8 *lna2_gain_db = NULL; 15247 - s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; 15248 - s8 *tia_gain_db; 15249 - s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; 15250 - s8 *tia_gainbits; 15251 - u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; 15252 - u16 *rfseq_init_gain; 15243 + static const s8 lna1G_gain_db_rev7[] = { 9, 14, 19, 24 }; 15244 + const s8 *lna1_gain_db = NULL; 15245 + const s8 *lna1_gain_db_2 = NULL; 15246 + const s8 *lna2_gain_db = NULL; 15247 + static const s8 tiaA_gain_db_rev7[] = { -9, -6, -3, 0, 3, 3, 3, 3, 3, 3 }; 15248 + const s8 *tia_gain_db; 15249 + static const s8 tiaA_gainbits_rev7[] = { 0, 1, 2, 3, 4, 4, 4, 4, 4, 4 }; 15250 + const s8 *tia_gainbits; 15251 + static const u16 rfseqA_init_gain_rev7[] = { 0x624f, 0x624f }; 15252 + const u16 *rfseq_init_gain; 15253 15253 u16 init_gaincode; 15254 15254 u16 clip1hi_gaincode; 15255 15255 u16 clip1md_gaincode = 0; ··· 15310 15310 15311 15311 if ((freq <= 5080) || (freq == 5825)) { 15312 15312 15313 - s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; 15314 - s8 lna1A_gain_db_2_rev7[] = { 15315 - 11, 17, 22, 25}; 15316 - s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; 15313 + static const s8 lna1A_gain_db_rev7[] = { 11, 16, 20, 24 }; 15314 + static const s8 lna1A_gain_db_2_rev7[] = { 11, 17, 22, 25}; 15315 + static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; 15317 15316 15318 15317 crsminu_th = 0x3e; 15319 15318 lna1_gain_db = lna1A_gain_db_rev7; ··· 15320 15321 lna2_gain_db = lna2A_gain_db_rev7; 15321 15322 } else if ((freq >= 5500) && (freq <= 5700)) { 15322 15323 15323 - s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; 15324 - s8 lna1A_gain_db_2_rev7[] = { 15325 - 12, 18, 22, 26}; 15326 - s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; 15324 + static const s8 lna1A_gain_db_rev7[] = { 11, 17, 21, 25 }; 15325 + static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26}; 15326 + static const s8 lna2A_gain_db_rev7[] = { 1, 8, 12, 16 }; 15327 15327 15328 15328 crsminu_th = 0x45; 15329 15329 clip1md_gaincode_B = 0x14; ··· 15333 15335 lna2_gain_db = lna2A_gain_db_rev7; 15334 15336 } else { 15335 15337 15336 - s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; 15337 - s8 lna1A_gain_db_2_rev7[] = { 15338 - 12, 18, 22, 26}; 15339 - s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; 15338 + static const s8 lna1A_gain_db_rev7[] = { 12, 18, 22, 26 }; 15339 + static const s8 lna1A_gain_db_2_rev7[] = { 12, 18, 22, 26}; 15340 + static const s8 lna2A_gain_db_rev7[] = { -1, 6, 10, 14 }; 15340 15341 15341 15342 crsminu_th = 0x41; 15342 15343 lna1_gain_db = lna1A_gain_db_rev7; ··· 15447 15450 NPHY_RFSEQ_CMD_CLR_HIQ_DIS, 15448 15451 NPHY_RFSEQ_CMD_SET_HPF_BW 15449 15452 }; 15450 - u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; 15451 - s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; 15452 - s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; 15453 - s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; 15454 - s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; 15455 - s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; 15456 - s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; 15457 - s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; 15458 - s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; 15459 - s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; 15460 - s8 *lna1_gain_db = NULL; 15461 - s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; 15462 - s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; 15463 - s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; 15464 - s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; 15465 - s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; 15466 - s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; 15467 - s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; 15468 - s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; 15469 - s8 *lna2_gain_db = NULL; 15470 - s8 tiaG_gain_db[] = { 15453 + static const u8 rfseq_updategainu_dlys[] = { 10, 30, 1 }; 15454 + static const s8 lna1G_gain_db[] = { 7, 11, 16, 23 }; 15455 + static const s8 lna1G_gain_db_rev4[] = { 8, 12, 17, 25 }; 15456 + static const s8 lna1G_gain_db_rev5[] = { 9, 13, 18, 26 }; 15457 + static const s8 lna1G_gain_db_rev6[] = { 8, 13, 18, 25 }; 15458 + static const s8 lna1G_gain_db_rev6_224B0[] = { 10, 14, 19, 27 }; 15459 + static const s8 lna1A_gain_db[] = { 7, 11, 17, 23 }; 15460 + static const s8 lna1A_gain_db_rev4[] = { 8, 12, 18, 23 }; 15461 + static const s8 lna1A_gain_db_rev5[] = { 6, 10, 16, 21 }; 15462 + static const s8 lna1A_gain_db_rev6[] = { 6, 10, 16, 21 }; 15463 + const s8 *lna1_gain_db = NULL; 15464 + static const s8 lna2G_gain_db[] = { -5, 6, 10, 14 }; 15465 + static const s8 lna2G_gain_db_rev5[] = { -3, 7, 11, 16 }; 15466 + static const s8 lna2G_gain_db_rev6[] = { -5, 6, 10, 14 }; 15467 + static const s8 lna2G_gain_db_rev6_224B0[] = { -5, 6, 10, 15 }; 15468 + static const s8 lna2A_gain_db[] = { -6, 2, 6, 10 }; 15469 + static const s8 lna2A_gain_db_rev4[] = { -5, 2, 6, 10 }; 15470 + static const s8 lna2A_gain_db_rev5[] = { -7, 0, 4, 8 }; 15471 + static const s8 lna2A_gain_db_rev6[] = { -7, 0, 4, 8 }; 15472 + const s8 *lna2_gain_db = NULL; 15473 + static const s8 tiaG_gain_db[] = { 15471 15474 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A }; 15472 - s8 tiaA_gain_db[] = { 15475 + static const s8 tiaA_gain_db[] = { 15473 15476 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13 }; 15474 - s8 tiaA_gain_db_rev4[] = { 15477 + static const s8 tiaA_gain_db_rev4[] = { 15475 15478 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; 15476 - s8 tiaA_gain_db_rev5[] = { 15479 + static const s8 tiaA_gain_db_rev5[] = { 15477 15480 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; 15478 - s8 tiaA_gain_db_rev6[] = { 15481 + static const s8 tiaA_gain_db_rev6[] = { 15479 15482 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d }; 15480 - s8 *tia_gain_db; 15481 - s8 tiaG_gainbits[] = { 15483 + const s8 *tia_gain_db; 15484 + static const s8 tiaG_gainbits[] = { 15482 15485 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 }; 15483 - s8 tiaA_gainbits[] = { 15486 + static const s8 tiaA_gainbits[] = { 15484 15487 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06 }; 15485 - s8 tiaA_gainbits_rev4[] = { 15488 + static const s8 tiaA_gainbits_rev4[] = { 15486 15489 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; 15487 - s8 tiaA_gainbits_rev5[] = { 15490 + static const s8 tiaA_gainbits_rev5[] = { 15488 15491 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; 15489 - s8 tiaA_gainbits_rev6[] = { 15492 + static const s8 tiaA_gainbits_rev6[] = { 15490 15493 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04 }; 15491 - s8 *tia_gainbits; 15492 - s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; 15493 - s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; 15494 - u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; 15495 - u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; 15496 - u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; 15497 - u16 rfseqG_init_gain_rev5_elna[] = { 15494 + const s8 *tia_gainbits; 15495 + static const s8 lpf_gain_db[] = { 0x00, 0x06, 0x0c, 0x12, 0x12, 0x12 }; 15496 + static const s8 lpf_gainbits[] = { 0x00, 0x01, 0x02, 0x03, 0x03, 0x03 }; 15497 + static const u16 rfseqG_init_gain[] = { 0x613f, 0x613f, 0x613f, 0x613f }; 15498 + static const u16 rfseqG_init_gain_rev4[] = { 0x513f, 0x513f, 0x513f, 0x513f }; 15499 + static const u16 rfseqG_init_gain_rev5[] = { 0x413f, 0x413f, 0x413f, 0x413f }; 15500 + static const u16 rfseqG_init_gain_rev5_elna[] = { 15498 15501 0x013f, 0x013f, 0x013f, 0x013f }; 15499 - u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; 15500 - u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; 15501 - u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; 15502 - u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; 15503 - u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; 15504 - u16 rfseqA_init_gain_rev4_elna[] = { 15502 + static const u16 rfseqG_init_gain_rev6[] = { 0x513f, 0x513f }; 15503 + static const u16 rfseqG_init_gain_rev6_224B0[] = { 0x413f, 0x413f }; 15504 + static const u16 rfseqG_init_gain_rev6_elna[] = { 0x113f, 0x113f }; 15505 + static const u16 rfseqA_init_gain[] = { 0x516f, 0x516f, 0x516f, 0x516f }; 15506 + static const u16 rfseqA_init_gain_rev4[] = { 0x614f, 0x614f, 0x614f, 0x614f }; 15507 + static const u16 rfseqA_init_gain_rev4_elna[] = { 15505 15508 0x314f, 0x314f, 0x314f, 0x314f }; 15506 - u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; 15507 - u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; 15508 - u16 *rfseq_init_gain; 15509 + static const u16 rfseqA_init_gain_rev5[] = { 0x714f, 0x714f, 0x714f, 0x714f }; 15510 + static const u16 rfseqA_init_gain_rev6[] = { 0x714f, 0x714f }; 15511 + const u16 *rfseq_init_gain; 15509 15512 u16 initG_gaincode = 0x627e; 15510 15513 u16 initG_gaincode_rev4 = 0x527e; 15511 15514 u16 initG_gaincode_rev5 = 0x427e; ··· 15535 15538 u16 clip1mdA_gaincode_rev6 = 0x2084; 15536 15539 u16 clip1md_gaincode = 0; 15537 15540 u16 clip1loG_gaincode = 0x0074; 15538 - u16 clip1loG_gaincode_rev5[] = { 15541 + static const u16 clip1loG_gaincode_rev5[] = { 15539 15542 0x0062, 0x0064, 0x006a, 0x106a, 0x106c, 0x1074, 0x107c, 0x207c 15540 15543 }; 15541 - u16 clip1loG_gaincode_rev6[] = { 15544 + static const u16 clip1loG_gaincode_rev6[] = { 15542 15545 0x106a, 0x106c, 0x1074, 0x107c, 0x007e, 0x107e, 0x207e, 0x307e 15543 15546 }; 15544 15547 u16 clip1loG_gaincode_rev6_224B0 = 0x1074; ··· 16063 16066 16064 16067 static void wlc_phy_workarounds_nphy(struct brcms_phy *pi) 16065 16068 { 16066 - u8 rfseq_rx2tx_events[] = { 16069 + static const u8 rfseq_rx2tx_events[] = { 16067 16070 NPHY_RFSEQ_CMD_NOP, 16068 16071 NPHY_RFSEQ_CMD_RXG_FBW, 16069 16072 NPHY_RFSEQ_CMD_TR_SWITCH, ··· 16073 16076 NPHY_RFSEQ_CMD_EXT_PA 16074 16077 }; 16075 16078 u8 rfseq_rx2tx_dlys[] = { 8, 6, 6, 2, 4, 60, 1 }; 16076 - u8 rfseq_tx2rx_events[] = { 16079 + static const u8 rfseq_tx2rx_events[] = { 16077 16080 NPHY_RFSEQ_CMD_NOP, 16078 16081 NPHY_RFSEQ_CMD_EXT_PA, 16079 16082 NPHY_RFSEQ_CMD_TX_GAIN, ··· 16082 16085 NPHY_RFSEQ_CMD_RXG_FBW, 16083 16086 NPHY_RFSEQ_CMD_CLR_HIQ_DIS 16084 16087 }; 16085 - u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; 16086 - u8 rfseq_tx2rx_events_rev3[] = { 16088 + static const u8 rfseq_tx2rx_dlys[] = { 8, 6, 2, 4, 4, 6, 1 }; 16089 + static const u8 rfseq_tx2rx_events_rev3[] = { 16087 16090 NPHY_REV3_RFSEQ_CMD_EXT_PA, 16088 16091 NPHY_REV3_RFSEQ_CMD_INT_PA_PU, 16089 16092 NPHY_REV3_RFSEQ_CMD_TX_GAIN, ··· 16093 16096 NPHY_REV3_RFSEQ_CMD_CLR_HIQ_DIS, 16094 16097 NPHY_REV3_RFSEQ_CMD_END 16095 16098 }; 16096 - u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; 16099 + static const u8 rfseq_tx2rx_dlys_rev3[] = { 8, 4, 2, 2, 4, 4, 6, 1 }; 16097 16100 u8 rfseq_rx2tx_events_rev3[] = { 16098 16101 NPHY_REV3_RFSEQ_CMD_NOP, 16099 16102 NPHY_REV3_RFSEQ_CMD_RXG_FBW, ··· 16107 16110 }; 16108 16111 u8 rfseq_rx2tx_dlys_rev3[] = { 8, 6, 6, 4, 4, 18, 42, 1, 1 }; 16109 16112 16110 - u8 rfseq_rx2tx_events_rev3_ipa[] = { 16113 + static const u8 rfseq_rx2tx_events_rev3_ipa[] = { 16111 16114 NPHY_REV3_RFSEQ_CMD_NOP, 16112 16115 NPHY_REV3_RFSEQ_CMD_RXG_FBW, 16113 16116 NPHY_REV3_RFSEQ_CMD_TR_SWITCH, ··· 16118 16121 NPHY_REV3_RFSEQ_CMD_INT_PA_PU, 16119 16122 NPHY_REV3_RFSEQ_CMD_END 16120 16123 }; 16121 - u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; 16122 - u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; 16124 + static const u8 rfseq_rx2tx_dlys_rev3_ipa[] = { 8, 6, 6, 4, 4, 16, 43, 1, 1 }; 16125 + static const u16 rfseq_rx2tx_dacbufpu_rev7[] = { 0x10f, 0x10f }; 16123 16126 16124 16127 s16 alpha0, alpha1, alpha2; 16125 16128 s16 beta0, beta1, beta2; 16126 16129 u32 leg_data_weights, ht_data_weights, nss1_data_weights, 16127 16130 stbc_data_weights; 16128 16131 u8 chan_freq_range = 0; 16129 - u16 dac_control = 0x0002; 16132 + static const u16 dac_control = 0x0002; 16130 16133 u16 aux_adc_vmid_rev7_core0[] = { 0x8e, 0x96, 0x96, 0x96 }; 16131 16134 u16 aux_adc_vmid_rev7_core1[] = { 0x8f, 0x9f, 0x9f, 0x96 }; 16132 16135 u16 aux_adc_vmid_rev4[] = { 0xa2, 0xb4, 0xb4, 0x89 }; ··· 16136 16139 u16 aux_adc_gain_rev4[] = { 0x02, 0x02, 0x02, 0x00 }; 16137 16140 u16 aux_adc_gain_rev3[] = { 0x02, 0x02, 0x02, 0x00 }; 16138 16141 u16 *aux_adc_gain; 16139 - u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; 16140 - u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; 16142 + static const u16 sk_adc_vmid[] = { 0xb4, 0xb4, 0xb4, 0x24 }; 16143 + static const u16 sk_adc_gain[] = { 0x02, 0x02, 0x02, 0x02 }; 16141 16144 s32 min_nvar_val = 0x18d; 16142 16145 s32 min_nvar_offset_6mbps = 20; 16143 16146 u8 pdetrange; ··· 16148 16151 u16 rfseq_rx2tx_lpf_h_hpc_rev7 = 0x77; 16149 16152 u16 rfseq_tx2rx_lpf_h_hpc_rev7 = 0x77; 16150 16153 u16 rfseq_pktgn_lpf_h_hpc_rev7 = 0x77; 16151 - u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; 16152 - u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; 16153 - u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; 16154 + static const u16 rfseq_htpktgn_lpf_hpc_rev7[] = { 0x77, 0x11, 0x11 }; 16155 + static const u16 rfseq_pktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; 16156 + static const u16 rfseq_cckpktgn_lpf_hpc_rev7[] = { 0x11, 0x11 }; 16154 16157 u16 ipalvlshift_3p3_war_en = 0; 16155 16158 u16 rccal_bcap_val, rccal_scap_val; 16156 16159 u16 rccal_tx20_11b_bcap = 0; ··· 24288 24291 u16 bbmult; 24289 24292 u16 tblentry; 24290 24293 24291 - struct nphy_txiqcal_ladder ladder_lo[] = { 24294 + static const struct nphy_txiqcal_ladder ladder_lo[] = { 24292 24295 {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, 24293 24296 {25, 0}, {25, 1}, {25, 2}, {25, 3}, {25, 4}, {25, 5}, 24294 24297 {25, 6}, {25, 7}, {35, 7}, {50, 7}, {71, 7}, {100, 7} 24295 24298 }; 24296 24299 24297 - struct nphy_txiqcal_ladder ladder_iq[] = { 24300 + static const struct nphy_txiqcal_ladder ladder_iq[] = { 24298 24301 {3, 0}, {4, 0}, {6, 0}, {9, 0}, {13, 0}, {18, 0}, 24299 24302 {25, 0}, {35, 0}, {50, 0}, {71, 0}, {100, 0}, {100, 1}, 24300 24303 {100, 2}, {100, 3}, {100, 4}, {100, 5}, {100, 6}, {100, 7} ··· 25770 25773 u16 cal_gain[2]; 25771 25774 struct nphy_iqcal_params cal_params[2]; 25772 25775 u32 tbl_len; 25773 - void *tbl_ptr; 25776 + const void *tbl_ptr; 25774 25777 bool ladder_updated[2]; 25775 25778 u8 mphase_cal_lastphase = 0; 25776 25779 int bcmerror = 0; 25777 25780 bool phyhang_avoid_state = false; 25778 25781 25779 - u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { 25782 + static const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = { 25780 25783 0x0300, 0x0500, 0x0700, 0x0900, 0x0d00, 0x1100, 0x1900, 0x1901, 25781 25784 0x1902, 25782 25785 0x1903, 0x1904, 0x1905, 0x1906, 0x1907, 0x2407, 0x3207, 0x4607, 25783 25786 0x6407 25784 25787 }; 25785 25788 25786 - u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { 25789 + static const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = { 25787 25790 0x0200, 0x0300, 0x0600, 0x0900, 0x0d00, 0x1100, 0x1900, 0x2400, 25788 25791 0x3200, 25789 25792 0x4600, 0x6400, 0x6401, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, 25790 25793 0x6407 25791 25794 }; 25792 25795 25793 - u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { 25796 + static const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = { 25794 25797 0x0200, 0x0300, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1201, 25795 25798 0x1202, 25796 25799 0x1203, 0x1204, 0x1205, 0x1206, 0x1207, 0x1907, 0x2307, 0x3207, 25797 25800 0x4707 25798 25801 }; 25799 25802 25800 - u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { 25803 + static const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = { 25801 25804 0x0100, 0x0200, 0x0400, 0x0700, 0x0900, 0x0c00, 0x1200, 0x1900, 25802 25805 0x2300, 25803 25806 0x3200, 0x4700, 0x4701, 0x4702, 0x4703, 0x4704, 0x4705, 0x4706, 25804 25807 0x4707 25805 25808 }; 25806 25809 25807 - u16 tbl_tx_iqlo_cal_startcoefs[] = { 25810 + static const u16 tbl_tx_iqlo_cal_startcoefs[] = { 25808 25811 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 25809 25812 0x0000 25810 25813 }; 25811 25814 25812 - u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { 25815 + static const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = { 25813 25816 0x8123, 0x8264, 0x8086, 0x8245, 0x8056, 25814 25817 0x9123, 0x9264, 0x9086, 0x9245, 0x9056 25815 25818 }; 25816 25819 25817 - u16 tbl_tx_iqlo_cal_cmds_recal[] = { 25820 + static const u16 tbl_tx_iqlo_cal_cmds_recal[] = { 25818 25821 0x8101, 0x8253, 0x8053, 0x8234, 0x8034, 25819 25822 0x9101, 0x9253, 0x9053, 0x9234, 0x9034 25820 25823 }; 25821 25824 25822 - u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { 25825 + static const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[] = { 25823 25826 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 25824 25827 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 25825 25828 0x0000 25826 25829 }; 25827 25830 25828 - u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { 25831 + static const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = { 25829 25832 0x8434, 0x8334, 0x8084, 0x8267, 0x8056, 0x8234, 25830 25833 0x9434, 0x9334, 0x9084, 0x9267, 0x9056, 0x9234 25831 25834 }; 25832 25835 25833 - u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { 25836 + static const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = { 25834 25837 0x8423, 0x8323, 0x8073, 0x8256, 0x8045, 0x8223, 25835 25838 0x9423, 0x9323, 0x9073, 0x9256, 0x9045, 0x9223 25836 25839 };
+1
drivers/net/wireless/intel/iwlwifi/cfg/7000.c
··· 309 309 .nvm_calib_ver = IWL3168_TX_POWER_VERSION, 310 310 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 311 311 .dccm_len = IWL7265_DCCM_LEN, 312 + .nvm_type = IWL_NVM_SDP, 312 313 }; 313 314 314 315 const struct iwl_cfg iwl7265_2ac_cfg = {
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/8000.c
··· 164 164 .default_nvm_file_C_step = DEFAULT_NVM_FILE_FAMILY_8000C, \ 165 165 .thermal_params = &iwl8000_tt_params, \ 166 166 .apmg_not_supported = true, \ 167 - .ext_nvm = true, \ 167 + .nvm_type = IWL_NVM_EXT, \ 168 168 .dbgc_supported = true 169 169 170 170 #define IWL_DEVICE_8000 \
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/9000.c
··· 148 148 .vht_mu_mimo_supported = true, \ 149 149 .mac_addr_from_csr = true, \ 150 150 .rf_id = true, \ 151 - .ext_nvm = true, \ 151 + .nvm_type = IWL_NVM_EXT, \ 152 152 .dbgc_supported = true 153 153 154 154 const struct iwl_cfg iwl9160_2ac_cfg = {
+1 -1
drivers/net/wireless/intel/iwlwifi/cfg/a000.c
··· 133 133 .use_tfh = true, \ 134 134 .rf_id = true, \ 135 135 .gen2 = true, \ 136 - .ext_nvm = true, \ 136 + .nvm_type = IWL_NVM_EXT, \ 137 137 .dbgc_supported = true 138 138 139 139 const struct iwl_cfg iwla000_2ac_cfg_hr = {
+2
drivers/net/wireless/intel/iwlwifi/fw/api/nvm-reg.h
··· 108 108 * @NVM_SECTION_TYPE_REGULATORY: regulatory section 109 109 * @NVM_SECTION_TYPE_CALIBRATION: calibration section 110 110 * @NVM_SECTION_TYPE_PRODUCTION: production section 111 + * @NVM_SECTION_TYPE_REGULATORY_SDP: regulatory section used by 3168 series 111 112 * @NVM_SECTION_TYPE_MAC_OVERRIDE: MAC override section 112 113 * @NVM_SECTION_TYPE_PHY_SKU: PHY SKU section 113 114 * @NVM_MAX_NUM_SECTIONS: number of sections ··· 118 117 NVM_SECTION_TYPE_REGULATORY = 3, 119 118 NVM_SECTION_TYPE_CALIBRATION = 4, 120 119 NVM_SECTION_TYPE_PRODUCTION = 5, 120 + NVM_SECTION_TYPE_REGULATORY_SDP = 8, 121 121 NVM_SECTION_TYPE_MAC_OVERRIDE = 11, 122 122 NVM_SECTION_TYPE_PHY_SKU = 12, 123 123 NVM_MAX_NUM_SECTIONS = 13,
+2 -5
drivers/net/wireless/intel/iwlwifi/fw/dbg.c
··· 1086 1086 1087 1087 if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 1088 1088 /* stop recording */ 1089 - iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100); 1089 + iwl_fw_dbg_stop_recording(fwrt); 1090 1090 1091 1091 iwl_fw_error_dump(fwrt); 1092 1092 ··· 1104 1104 u32 in_sample = iwl_read_prph(fwrt->trans, DBGC_IN_SAMPLE); 1105 1105 u32 out_ctrl = iwl_read_prph(fwrt->trans, DBGC_OUT_CTRL); 1106 1106 1107 - /* stop recording */ 1108 - iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0); 1109 - udelay(100); 1110 - iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0); 1107 + iwl_fw_dbg_stop_recording(fwrt); 1111 1108 /* wait before we collect the data till the DBGC stop */ 1112 1109 udelay(500); 1113 1110
+15
drivers/net/wireless/intel/iwlwifi/fw/dbg.h
··· 68 68 #include <linux/workqueue.h> 69 69 #include <net/cfg80211.h> 70 70 #include "runtime.h" 71 + #include "iwl-prph.h" 72 + #include "iwl-io.h" 71 73 #include "file.h" 72 74 #include "error-dump.h" 73 75 ··· 196 194 iwl_fw_dbg_get_trigger((fwrt)->fw,\ 197 195 (trig))) 198 196 197 + static inline void iwl_fw_dbg_stop_recording(struct iwl_fw_runtime *fwrt) 198 + { 199 + if (fwrt->trans->cfg->device_family == IWL_DEVICE_FAMILY_7000) { 200 + iwl_set_bits_prph(fwrt->trans, MON_BUFF_SAMPLE_CTL, 0x100); 201 + } else { 202 + iwl_write_prph(fwrt->trans, DBGC_IN_SAMPLE, 0); 203 + udelay(100); 204 + iwl_write_prph(fwrt->trans, DBGC_OUT_CTRL, 0); 205 + } 206 + } 207 + 199 208 static inline void iwl_fw_dump_conf_clear(struct iwl_fw_runtime *fwrt) 200 209 { 210 + iwl_fw_dbg_stop_recording(fwrt); 211 + 201 212 fwrt->dump.conf = FW_DBG_INVALID; 202 213 } 203 214
+14 -2
drivers/net/wireless/intel/iwlwifi/iwl-config.h
··· 108 108 IWL_LED_DISABLE, 109 109 }; 110 110 111 + /** 112 + * enum iwl_nvm_type - nvm formats 113 + * @IWL_NVM: the regular format 114 + * @IWL_NVM_EXT: extended NVM format 115 + * @IWL_NVM_SDP: NVM format used by 3168 series 116 + */ 117 + enum iwl_nvm_type { 118 + IWL_NVM, 119 + IWL_NVM_EXT, 120 + IWL_NVM_SDP, 121 + }; 122 + 111 123 /* 112 124 * This is the threshold value of plcp error rate per 100mSecs. It is 113 125 * used to set and check for the validity of plcp_delta. ··· 332 320 * @integrated: discrete or integrated 333 321 * @gen2: a000 and on transport operation 334 322 * @cdb: CDB support 335 - * @ext_nvm: extended NVM format 323 + * @nvm_type: see &enum iwl_nvm_type 336 324 * 337 325 * We enable the driver to be backward compatible wrt. hardware features. 338 326 * API differences in uCode shouldn't be handled here but through TLVs ··· 354 342 const struct iwl_tt_params *thermal_params; 355 343 enum iwl_device_family device_family; 356 344 enum iwl_led_mode led_mode; 345 + enum iwl_nvm_type nvm_type; 357 346 u32 max_data_size; 358 347 u32 max_inst_size; 359 348 netdev_features_t features; ··· 382 369 use_tfh:1, 383 370 gen2:1, 384 371 cdb:1, 385 - ext_nvm:1, 386 372 dbgc_supported:1; 387 373 u8 valid_tx_ant; 388 374 u8 valid_rx_ant;
+62 -75
drivers/net/wireless/intel/iwlwifi/iwl-nvm-parse.c
··· 77 77 #include "iwl-csr.h" 78 78 79 79 /* NVM offsets (in words) definitions */ 80 - enum wkp_nvm_offsets { 80 + enum nvm_offsets { 81 81 /* NVM HW-Section offset (in words) definitions */ 82 82 SUBSYSTEM_ID = 0x0A, 83 83 HW_ADDR = 0x15, ··· 92 92 93 93 /* NVM calibration section offset (in words) definitions */ 94 94 NVM_CALIB_SECTION = 0x2B8, 95 - XTAL_CALIB = 0x316 - NVM_CALIB_SECTION 95 + XTAL_CALIB = 0x316 - NVM_CALIB_SECTION, 96 + 97 + /* NVM REGULATORY -Section offset (in words) definitions */ 98 + NVM_CHANNELS_SDP = 0, 96 99 }; 97 100 98 101 enum ext_nvm_offsets { ··· 209 206 NVM_CHANNEL_DC_HIGH = BIT(12), 210 207 }; 211 208 209 + static inline void iwl_nvm_print_channel_flags(struct device *dev, u32 level, 210 + int chan, u16 flags) 211 + { 212 212 #define CHECK_AND_PRINT_I(x) \ 213 - ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "") 213 + ((flags & NVM_CHANNEL_##x) ? " " #x : "") 214 + 215 + if (!(flags & NVM_CHANNEL_VALID)) { 216 + IWL_DEBUG_DEV(dev, level, "Ch. %d: 0x%x: No traffic\n", 217 + chan, flags); 218 + return; 219 + } 220 + 221 + /* Note: already can print up to 101 characters, 110 is the limit! */ 222 + IWL_DEBUG_DEV(dev, level, 223 + "Ch. %d: 0x%x:%s%s%s%s%s%s%s%s%s%s%s%s\n", 224 + chan, flags, 225 + CHECK_AND_PRINT_I(VALID), 226 + CHECK_AND_PRINT_I(IBSS), 227 + CHECK_AND_PRINT_I(ACTIVE), 228 + CHECK_AND_PRINT_I(RADAR), 229 + CHECK_AND_PRINT_I(INDOOR_ONLY), 230 + CHECK_AND_PRINT_I(GO_CONCURRENT), 231 + CHECK_AND_PRINT_I(UNIFORM), 232 + CHECK_AND_PRINT_I(20MHZ), 233 + CHECK_AND_PRINT_I(40MHZ), 234 + CHECK_AND_PRINT_I(80MHZ), 235 + CHECK_AND_PRINT_I(160MHZ), 236 + CHECK_AND_PRINT_I(DC_HIGH)); 237 + #undef CHECK_AND_PRINT_I 238 + } 214 239 215 240 static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz, 216 241 u16 nvm_flags, const struct iwl_cfg *cfg) ··· 246 215 u32 flags = IEEE80211_CHAN_NO_HT40; 247 216 u32 last_5ghz_ht = LAST_5GHZ_HT; 248 217 249 - if (cfg->ext_nvm) 218 + if (cfg->nvm_type == IWL_NVM_EXT) 250 219 last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; 251 220 252 221 if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) { ··· 299 268 int num_of_ch, num_2ghz_channels; 300 269 const u8 *nvm_chan; 301 270 302 - if (!cfg->ext_nvm) { 271 + if (cfg->nvm_type != IWL_NVM_EXT) { 303 272 num_of_ch = IWL_NUM_CHANNELS; 304 273 nvm_chan = &iwl_nvm_channels[0]; 305 274 num_2ghz_channels = NUM_2GHZ_CHANNELS; ··· 333 302 * supported, hence we still want to add them to 334 303 * the list of supported channels to cfg80211. 335 304 */ 336 - IWL_DEBUG_EEPROM(dev, 337 - "Ch. %d Flags %x [%sGHz] - No traffic\n", 338 - nvm_chan[ch_idx], 339 - ch_flags, 340 - (ch_idx >= num_2ghz_channels) ? 341 - "5.2" : "2.4"); 305 + iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, 306 + nvm_chan[ch_idx], ch_flags); 342 307 continue; 343 308 } 344 309 ··· 364 337 else 365 338 channel->flags = 0; 366 339 367 - IWL_DEBUG_EEPROM(dev, 368 - "Ch. %d [%sGHz] flags 0x%x %s%s%s%s%s%s%s%s%s%s%s%s(%ddBm): Ad-Hoc %ssupported\n", 369 - channel->hw_value, 370 - is_5ghz ? "5.2" : "2.4", 371 - ch_flags, 372 - CHECK_AND_PRINT_I(VALID), 373 - CHECK_AND_PRINT_I(IBSS), 374 - CHECK_AND_PRINT_I(ACTIVE), 375 - CHECK_AND_PRINT_I(RADAR), 376 - CHECK_AND_PRINT_I(INDOOR_ONLY), 377 - CHECK_AND_PRINT_I(GO_CONCURRENT), 378 - CHECK_AND_PRINT_I(UNIFORM), 379 - CHECK_AND_PRINT_I(20MHZ), 380 - CHECK_AND_PRINT_I(40MHZ), 381 - CHECK_AND_PRINT_I(80MHZ), 382 - CHECK_AND_PRINT_I(160MHZ), 383 - CHECK_AND_PRINT_I(DC_HIGH), 384 - channel->max_power, 385 - ((ch_flags & NVM_CHANNEL_IBSS) && 386 - !(ch_flags & NVM_CHANNEL_RADAR)) 387 - ? "" : "not "); 340 + iwl_nvm_print_channel_flags(dev, IWL_DL_EEPROM, 341 + channel->hw_value, ch_flags); 342 + IWL_DEBUG_EEPROM(dev, "Ch. %d: %ddBm\n", 343 + channel->hw_value, channel->max_power); 388 344 } 389 345 390 346 return n_channels; ··· 494 484 static int iwl_get_sku(const struct iwl_cfg *cfg, const __le16 *nvm_sw, 495 485 const __le16 *phy_sku) 496 486 { 497 - if (!cfg->ext_nvm) 487 + if (cfg->nvm_type != IWL_NVM_EXT) 498 488 return le16_to_cpup(nvm_sw + SKU); 499 489 500 490 return le32_to_cpup((__le32 *)(phy_sku + SKU_FAMILY_8000)); ··· 502 492 503 493 static int iwl_get_nvm_version(const struct iwl_cfg *cfg, const __le16 *nvm_sw) 504 494 { 505 - if (!cfg->ext_nvm) 495 + if (cfg->nvm_type != IWL_NVM_EXT) 506 496 return le16_to_cpup(nvm_sw + NVM_VERSION); 507 497 else 508 498 return le32_to_cpup((__le32 *)(nvm_sw + ··· 512 502 static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, const __le16 *nvm_sw, 513 503 const __le16 *phy_sku) 514 504 { 515 - if (!cfg->ext_nvm) 505 + if (cfg->nvm_type != IWL_NVM_EXT) 516 506 return le16_to_cpup(nvm_sw + RADIO_CFG); 517 507 518 508 return le32_to_cpup((__le32 *)(phy_sku + RADIO_CFG_FAMILY_EXT_NVM)); ··· 523 513 { 524 514 int n_hw_addr; 525 515 526 - if (!cfg->ext_nvm) 516 + if (cfg->nvm_type != IWL_NVM_EXT) 527 517 return le16_to_cpup(nvm_sw + N_HW_ADDRS); 528 518 529 519 n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)); ··· 535 525 struct iwl_nvm_data *data, 536 526 u32 radio_cfg) 537 527 { 538 - if (!cfg->ext_nvm) { 528 + if (cfg->nvm_type != IWL_NVM_EXT) { 539 529 data->radio_cfg_type = NVM_RF_CFG_TYPE_MSK(radio_cfg); 540 530 data->radio_cfg_step = NVM_RF_CFG_STEP_MSK(radio_cfg); 541 531 data->radio_cfg_dash = NVM_RF_CFG_DASH_MSK(radio_cfg); ··· 644 634 { 645 635 if (cfg->mac_addr_from_csr) { 646 636 iwl_set_hw_address_from_csr(trans, data); 647 - } else if (!cfg->ext_nvm) { 637 + } else if (cfg->nvm_type != IWL_NVM_EXT) { 648 638 const u8 *hw_addr = (const u8 *)(nvm_hw + HW_ADDR); 649 639 650 640 /* The byte order is little endian 16 bit, meaning 214365 */ ··· 716 706 u16 lar_config; 717 707 const __le16 *ch_section; 718 708 719 - if (!cfg->ext_nvm) 709 + if (cfg->nvm_type != IWL_NVM_EXT) 720 710 data = kzalloc(sizeof(*data) + 721 711 sizeof(struct ieee80211_channel) * 722 712 IWL_NUM_CHANNELS, ··· 750 740 751 741 data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); 752 742 753 - if (!cfg->ext_nvm) { 743 + if (cfg->nvm_type != IWL_NVM_EXT) { 754 744 /* Checking for required sections */ 755 745 if (!nvm_calib) { 756 746 IWL_ERR(trans, ··· 758 748 kfree(data); 759 749 return NULL; 760 750 } 751 + 752 + ch_section = cfg->nvm_type == IWL_NVM_SDP ? 753 + &regulatory[NVM_CHANNELS_SDP] : 754 + &nvm_sw[NVM_CHANNELS]; 755 + 761 756 /* in family 8000 Xtal calibration values moved to OTP */ 762 757 data->xtal_calib[0] = *(nvm_calib + XTAL_CALIB); 763 758 data->xtal_calib[1] = *(nvm_calib + XTAL_CALIB + 1); 764 759 lar_enabled = true; 765 - ch_section = &nvm_sw[NVM_CHANNELS]; 766 760 } else { 767 761 u16 lar_offset = data->nvm_version < 0xE39 ? 768 762 NVM_LAR_OFFSET_OLD : ··· 800 786 u32 flags = NL80211_RRF_NO_HT40; 801 787 u32 last_5ghz_ht = LAST_5GHZ_HT; 802 788 803 - if (cfg->ext_nvm) 789 + if (cfg->nvm_type == IWL_NVM_EXT) 804 790 last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000; 805 791 806 792 if (ch_idx < NUM_2GHZ_CHANNELS && ··· 848 834 int ch_idx; 849 835 u16 ch_flags; 850 836 u32 reg_rule_flags, prev_reg_rule_flags = 0; 851 - const u8 *nvm_chan = cfg->ext_nvm ? 837 + const u8 *nvm_chan = cfg->nvm_type == IWL_NVM_EXT ? 852 838 iwl_ext_nvm_channels : iwl_nvm_channels; 853 839 struct ieee80211_regdomain *regd; 854 840 int size_of_regd; ··· 857 843 int center_freq, prev_center_freq = 0; 858 844 int valid_rules = 0; 859 845 bool new_rule; 860 - int max_num_ch = cfg->ext_nvm ? 846 + int max_num_ch = cfg->nvm_type == IWL_NVM_EXT ? 861 847 IWL_NUM_CHANNELS_EXT : IWL_NUM_CHANNELS; 862 848 863 849 if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES)) ··· 887 873 new_rule = false; 888 874 889 875 if (!(ch_flags & NVM_CHANNEL_VALID)) { 890 - IWL_DEBUG_DEV(dev, IWL_DL_LAR, 891 - "Ch. %d Flags %x [%sGHz] - No traffic\n", 892 - nvm_chan[ch_idx], 893 - ch_flags, 894 - (ch_idx >= NUM_2GHZ_CHANNELS) ? 895 - "5.2" : "2.4"); 876 + iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, 877 + nvm_chan[ch_idx], ch_flags); 896 878 continue; 897 879 } 898 880 ··· 924 914 prev_center_freq = center_freq; 925 915 prev_reg_rule_flags = reg_rule_flags; 926 916 927 - IWL_DEBUG_DEV(dev, IWL_DL_LAR, 928 - "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s%s%s%s(0x%02x)\n", 929 - center_freq, 930 - band == NL80211_BAND_5GHZ ? "5.2" : "2.4", 931 - CHECK_AND_PRINT_I(VALID), 932 - CHECK_AND_PRINT_I(IBSS), 933 - CHECK_AND_PRINT_I(ACTIVE), 934 - CHECK_AND_PRINT_I(RADAR), 935 - CHECK_AND_PRINT_I(INDOOR_ONLY), 936 - CHECK_AND_PRINT_I(GO_CONCURRENT), 937 - CHECK_AND_PRINT_I(UNIFORM), 938 - CHECK_AND_PRINT_I(20MHZ), 939 - CHECK_AND_PRINT_I(40MHZ), 940 - CHECK_AND_PRINT_I(80MHZ), 941 - CHECK_AND_PRINT_I(160MHZ), 942 - CHECK_AND_PRINT_I(DC_HIGH), 943 - ch_flags); 944 - IWL_DEBUG_DEV(dev, IWL_DL_LAR, 945 - "Ch. %d [%sGHz] reg_flags 0x%x: %s\n", 946 - center_freq, 947 - band == NL80211_BAND_5GHZ ? "5.2" : "2.4", 948 - reg_rule_flags, 949 - ((ch_flags & NVM_CHANNEL_ACTIVE) && 950 - !(ch_flags & NVM_CHANNEL_RADAR)) 951 - ? "Ad-Hoc" : ""); 917 + iwl_nvm_print_channel_flags(dev, IWL_DL_LAR, 918 + nvm_chan[ch_idx], ch_flags); 952 919 } 953 920 954 921 regd->n_reg_rules = valid_rules;
+7
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
··· 1077 1077 mvm->vif_count = 0; 1078 1078 mvm->rx_ba_sessions = 0; 1079 1079 mvm->fwrt.dump.conf = FW_DBG_INVALID; 1080 + mvm->monitor_on = false; 1080 1081 1081 1082 /* keep statistics ticking */ 1082 1083 iwl_mvm_accu_radio_stats(mvm); ··· 1438 1437 mvm->p2p_device_vif = vif; 1439 1438 } 1440 1439 1440 + if (vif->type == NL80211_IFTYPE_MONITOR) 1441 + mvm->monitor_on = true; 1442 + 1441 1443 iwl_mvm_vif_dbgfs_register(mvm, vif); 1442 1444 goto out_unlock; 1443 1445 ··· 1529 1525 1530 1526 iwl_mvm_power_update_mac(mvm); 1531 1527 iwl_mvm_mac_ctxt_remove(mvm, vif); 1528 + 1529 + if (vif->type == NL80211_IFTYPE_MONITOR) 1530 + mvm->monitor_on = false; 1532 1531 1533 1532 out_release: 1534 1533 mutex_unlock(&mvm->mutex);
+4 -1
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
··· 1015 1015 bool drop_bcn_ap_mode; 1016 1016 1017 1017 struct delayed_work cs_tx_unblock_dwork; 1018 + 1019 + /* does a monitor vif exist (only one can exist hence bool) */ 1020 + bool monitor_on; 1018 1021 #ifdef CONFIG_ACPI 1019 1022 struct iwl_mvm_sar_profile sar_profiles[IWL_MVM_SAR_PROFILE_NUM]; 1020 1023 struct iwl_mvm_geo_profile geo_profiles[IWL_NUM_GEO_PROFILES]; ··· 1162 1159 * Enable LAR only if it is supported by the FW (TLV) && 1163 1160 * enabled in the NVM 1164 1161 */ 1165 - if (mvm->cfg->ext_nvm) 1162 + if (mvm->cfg->nvm_type == IWL_NVM_EXT) 1166 1163 return nvm_lar && tlv_lar; 1167 1164 else 1168 1165 return tlv_lar;
+15 -6
drivers/net/wireless/intel/iwlwifi/mvm/nvm.c
··· 295 295 const __be16 *hw; 296 296 const __le16 *sw, *calib, *regulatory, *mac_override, *phy_sku; 297 297 bool lar_enabled; 298 + int regulatory_type; 298 299 299 300 /* Checking for required sections */ 300 - if (!mvm->trans->cfg->ext_nvm) { 301 + if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) { 301 302 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || 302 303 !mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data) { 303 304 IWL_ERR(mvm, "Can't parse empty OTP/NVM sections\n"); 304 305 return NULL; 305 306 } 306 307 } else { 308 + if (mvm->trans->cfg->nvm_type == IWL_NVM_SDP) 309 + regulatory_type = NVM_SECTION_TYPE_REGULATORY_SDP; 310 + else 311 + regulatory_type = NVM_SECTION_TYPE_REGULATORY; 312 + 307 313 /* SW and REGULATORY sections are mandatory */ 308 314 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || 309 - !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) { 315 + !mvm->nvm_sections[regulatory_type].data) { 310 316 IWL_ERR(mvm, 311 317 "Can't parse empty family 8000 OTP/NVM sections\n"); 312 318 return NULL; ··· 336 330 hw = (const __be16 *)sections[mvm->cfg->nvm_hw_section_num].data; 337 331 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; 338 332 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; 339 - regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data; 340 333 mac_override = 341 334 (const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data; 342 335 phy_sku = (const __le16 *)sections[NVM_SECTION_TYPE_PHY_SKU].data; 336 + 337 + regulatory = mvm->trans->cfg->nvm_type == IWL_NVM_SDP ? 338 + (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY_SDP].data : 339 + (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data; 343 340 344 341 lar_enabled = !iwlwifi_mod_params.lar_disable && 345 342 fw_has_capa(&mvm->fw->ucode_capa, ··· 403 394 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from external NVM\n"); 404 395 405 396 /* Maximal size depends on NVM version */ 406 - if (!mvm->trans->cfg->ext_nvm) 397 + if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) 407 398 max_section_size = IWL_MAX_NVM_SECTION_SIZE; 408 399 else 409 400 max_section_size = IWL_MAX_EXT_NVM_SECTION_SIZE; ··· 474 465 break; 475 466 } 476 467 477 - if (!mvm->trans->cfg->ext_nvm) { 468 + if (mvm->trans->cfg->nvm_type != IWL_NVM_EXT) { 478 469 section_size = 479 470 2 * NVM_WORD1_LEN(le16_to_cpu(file_sec->word1)); 480 471 section_id = NVM_WORD2_ID(le16_to_cpu(file_sec->word2)); ··· 749 740 struct ieee80211_regdomain *regd; 750 741 char mcc[3]; 751 742 752 - if (mvm->cfg->ext_nvm) { 743 + if (mvm->cfg->nvm_type == IWL_NVM_EXT) { 753 744 tlv_lar = fw_has_capa(&mvm->fw->ucode_capa, 754 745 IWL_UCODE_TLV_CAPA_LAR_SUPPORT); 755 746 nvm_lar = mvm->nvm_data->lar_enabled;
+3 -1
drivers/net/wireless/intel/iwlwifi/mvm/rx.c
··· 244 244 return 0; 245 245 246 246 default: 247 - IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); 247 + /* Expected in monitor (not having the keys) */ 248 + if (!mvm->monitor_on) 249 + IWL_ERR(mvm, "Unhandled alg: 0x%x\n", rx_pkt_status); 248 250 } 249 251 250 252 return 0;
+3 -1
drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
··· 277 277 stats->flag |= RX_FLAG_DECRYPTED; 278 278 return 0; 279 279 default: 280 - IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status); 280 + /* Expected in monitor (not having the keys) */ 281 + if (!mvm->monitor_on) 282 + IWL_ERR(mvm, "Unhandled alg: 0x%x\n", status); 281 283 } 282 284 283 285 return 0;
+1 -1
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
··· 631 631 632 632 if (!iwl_mvm_firmware_running(mvm) || 633 633 mvm->fwrt.cur_fw_img != IWL_UCODE_REGULAR) { 634 - ret = -EIO; 634 + ret = -ENODATA; 635 635 goto out; 636 636 } 637 637
+1 -1
drivers/net/wireless/realtek/rtlwifi/rtl8821ae/hw.c
··· 1122 1122 } 1123 1123 if (0 == tmp) { 1124 1124 read_addr = REG_DBI_RDATA + addr % 4; 1125 - ret = rtl_read_byte(rtlpriv, read_addr); 1125 + ret = rtl_read_word(rtlpriv, read_addr); 1126 1126 } 1127 1127 return ret; 1128 1128 }
+27 -12
drivers/of/of_mdio.c
··· 44 44 return -EINVAL; 45 45 } 46 46 47 - static void of_mdiobus_register_phy(struct mii_bus *mdio, 47 + static int of_mdiobus_register_phy(struct mii_bus *mdio, 48 48 struct device_node *child, u32 addr) 49 49 { 50 50 struct phy_device *phy; ··· 60 60 else 61 61 phy = get_phy_device(mdio, addr, is_c45); 62 62 if (IS_ERR(phy)) 63 - return; 63 + return PTR_ERR(phy); 64 64 65 - rc = irq_of_parse_and_map(child, 0); 65 + rc = of_irq_get(child, 0); 66 + if (rc == -EPROBE_DEFER) { 67 + phy_device_free(phy); 68 + return rc; 69 + } 66 70 if (rc > 0) { 67 71 phy->irq = rc; 68 72 mdio->irq[addr] = rc; ··· 88 84 if (rc) { 89 85 phy_device_free(phy); 90 86 of_node_put(child); 91 - return; 87 + return rc; 92 88 } 93 89 94 90 dev_dbg(&mdio->dev, "registered phy %s at address %i\n", 95 91 child->name, addr); 92 + return 0; 96 93 } 97 94 98 - static void of_mdiobus_register_device(struct mii_bus *mdio, 99 - struct device_node *child, u32 addr) 95 + static int of_mdiobus_register_device(struct mii_bus *mdio, 96 + struct device_node *child, u32 addr) 100 97 { 101 98 struct mdio_device *mdiodev; 102 99 int rc; 103 100 104 101 mdiodev = mdio_device_create(mdio, addr); 105 102 if (IS_ERR(mdiodev)) 106 - return; 103 + return PTR_ERR(mdiodev); 107 104 108 105 /* Associate the OF node with the device structure so it 109 106 * can be looked up later. ··· 117 112 if (rc) { 118 113 mdio_device_free(mdiodev); 119 114 of_node_put(child); 120 - return; 115 + return rc; 121 116 } 122 117 123 118 dev_dbg(&mdio->dev, "registered mdio device %s at address %i\n", 124 119 child->name, addr); 120 + return 0; 125 121 } 126 122 127 123 /* The following is a list of PHY compatible strings which appear in ··· 225 219 } 226 220 227 221 if (of_mdiobus_child_is_phy(child)) 228 - of_mdiobus_register_phy(mdio, child, addr); 222 + rc = of_mdiobus_register_phy(mdio, child, addr); 229 223 else 230 - of_mdiobus_register_device(mdio, child, addr); 224 + rc = of_mdiobus_register_device(mdio, child, addr); 225 + if (rc) 226 + goto unregister; 231 227 } 232 228 233 229 if (!scanphys) ··· 250 242 dev_info(&mdio->dev, "scan phy %s at address %i\n", 251 243 child->name, addr); 252 244 253 - if (of_mdiobus_child_is_phy(child)) 254 - of_mdiobus_register_phy(mdio, child, addr); 245 + if (of_mdiobus_child_is_phy(child)) { 246 + rc = of_mdiobus_register_phy(mdio, child, addr); 247 + if (rc) 248 + goto unregister; 249 + } 255 250 } 256 251 } 257 252 258 253 return 0; 254 + 255 + unregister: 256 + mdiobus_unregister(mdio); 257 + return rc; 259 258 } 260 259 EXPORT_SYMBOL(of_mdiobus_register); 261 260
+1 -1
include/linux/filter.h
··· 728 728 void bpf_warn_invalid_xdp_action(u32 act); 729 729 void bpf_warn_invalid_xdp_redirect(u32 ifindex); 730 730 731 - struct sock *do_sk_redirect_map(void); 731 + struct sock *do_sk_redirect_map(struct sk_buff *skb); 732 732 733 733 #ifdef CONFIG_BPF_JIT 734 734 extern int bpf_jit_enable;
+3
include/linux/netdevice.h
··· 3694 3694 unsigned char name_assign_type, 3695 3695 void (*setup)(struct net_device *), 3696 3696 unsigned int txqs, unsigned int rxqs); 3697 + int dev_get_valid_name(struct net *net, struct net_device *dev, 3698 + const char *name); 3699 + 3697 3700 #define alloc_netdev(sizeof_priv, name, name_assign_type, setup) \ 3698 3701 alloc_netdev_mqs(sizeof_priv, name, name_assign_type, setup, 1, 1) 3699 3702
+1 -1
include/net/inet_sock.h
··· 96 96 kmemcheck_bitfield_end(flags); 97 97 u32 ir_mark; 98 98 union { 99 - struct ip_options_rcu *opt; 99 + struct ip_options_rcu __rcu *ireq_opt; 100 100 #if IS_ENABLED(CONFIG_IPV6) 101 101 struct { 102 102 struct ipv6_txoptions *ipv6_opt;
+5
include/net/tcp.h
··· 840 840 struct inet6_skb_parm h6; 841 841 #endif 842 842 } header; /* For incoming skbs */ 843 + struct { 844 + __u32 key; 845 + __u32 flags; 846 + struct bpf_map *map; 847 + } bpf; 843 848 }; 844 849 }; 845 850
+1 -1
kernel/bpf/arraymap.c
··· 98 98 array_size += (u64) attr->max_entries * elem_size * num_possible_cpus(); 99 99 100 100 if (array_size >= U32_MAX - PAGE_SIZE || 101 - elem_size > PCPU_MIN_UNIT_SIZE || bpf_array_alloc_percpu(array)) { 101 + bpf_array_alloc_percpu(array)) { 102 102 bpf_map_area_free(array); 103 103 return ERR_PTR(-ENOMEM); 104 104 }
+7 -3
kernel/bpf/devmap.c
··· 69 69 70 70 static u64 dev_map_bitmap_size(const union bpf_attr *attr) 71 71 { 72 - return BITS_TO_LONGS(attr->max_entries) * sizeof(unsigned long); 72 + return BITS_TO_LONGS((u64) attr->max_entries) * sizeof(unsigned long); 73 73 } 74 74 75 75 static struct bpf_map *dev_map_alloc(union bpf_attr *attr) ··· 77 77 struct bpf_dtab *dtab; 78 78 int err = -EINVAL; 79 79 u64 cost; 80 + 81 + if (!capable(CAP_NET_ADMIN)) 82 + return ERR_PTR(-EPERM); 80 83 81 84 /* check sanity of attributes */ 82 85 if (attr->max_entries == 0 || attr->key_size != 4 || ··· 114 111 err = -ENOMEM; 115 112 116 113 /* A per cpu bitfield with a bit per possible net device */ 117 - dtab->flush_needed = __alloc_percpu(dev_map_bitmap_size(attr), 118 - __alignof__(unsigned long)); 114 + dtab->flush_needed = __alloc_percpu_gfp(dev_map_bitmap_size(attr), 115 + __alignof__(unsigned long), 116 + GFP_KERNEL | __GFP_NOWARN); 119 117 if (!dtab->flush_needed) 120 118 goto free_dtab; 121 119
-4
kernel/bpf/hashtab.c
··· 317 317 */ 318 318 goto free_htab; 319 319 320 - if (percpu && round_up(htab->map.value_size, 8) > PCPU_MIN_UNIT_SIZE) 321 - /* make sure the size for pcpu_alloc() is reasonable */ 322 - goto free_htab; 323 - 324 320 htab->elem_size = sizeof(struct htab_elem) + 325 321 round_up(htab->map.key_size, 8); 326 322 if (percpu)
+18 -10
kernel/bpf/sockmap.c
··· 39 39 #include <linux/workqueue.h> 40 40 #include <linux/list.h> 41 41 #include <net/strparser.h> 42 + #include <net/tcp.h> 42 43 43 44 struct bpf_stab { 44 45 struct bpf_map map; ··· 102 101 return SK_DROP; 103 102 104 103 skb_orphan(skb); 104 + /* We need to ensure that BPF metadata for maps is also cleared 105 + * when we orphan the skb so that we don't have the possibility 106 + * to reference a stale map. 107 + */ 108 + TCP_SKB_CB(skb)->bpf.map = NULL; 105 109 skb->sk = psock->sock; 106 110 bpf_compute_data_end(skb); 111 + preempt_disable(); 107 112 rc = (*prog->bpf_func)(skb, prog->insnsi); 113 + preempt_enable(); 108 114 skb->sk = NULL; 109 115 110 116 return rc; ··· 122 114 struct sock *sk; 123 115 int rc; 124 116 125 - /* Because we use per cpu values to feed input from sock redirect 126 - * in BPF program to do_sk_redirect_map() call we need to ensure we 127 - * are not preempted. RCU read lock is not sufficient in this case 128 - * with CONFIG_PREEMPT_RCU enabled so we must be explicit here. 129 - */ 130 - preempt_disable(); 131 117 rc = smap_verdict_func(psock, skb); 132 118 switch (rc) { 133 119 case SK_REDIRECT: 134 - sk = do_sk_redirect_map(); 135 - preempt_enable(); 120 + sk = do_sk_redirect_map(skb); 136 121 if (likely(sk)) { 137 122 struct smap_psock *peer = smap_psock_sk(sk); 138 123 ··· 142 141 /* Fall through and free skb otherwise */ 143 142 case SK_DROP: 144 143 default: 145 - if (rc != SK_REDIRECT) 146 - preempt_enable(); 147 144 kfree_skb(skb); 148 145 } 149 146 } ··· 485 486 struct bpf_stab *stab; 486 487 int err = -EINVAL; 487 488 u64 cost; 489 + 490 + if (!capable(CAP_NET_ADMIN)) 491 + return ERR_PTR(-EPERM); 488 492 489 493 /* check sanity of attributes */ 490 494 if (attr->max_entries == 0 || attr->key_size != 4 || ··· 840 838 if (!skops.sk) { 841 839 fput(socket->file); 842 840 return -EINVAL; 841 + } 842 + 843 + if (skops.sk->sk_type != SOCK_STREAM || 844 + skops.sk->sk_protocol != IPPROTO_TCP) { 845 + fput(socket->file); 846 + return -EOPNOTSUPP; 843 847 } 844 848 845 849 err = sock_map_ctx_update_elem(&skops, map, key, flags);
+51 -14
kernel/bpf/verifier.c
··· 1116 1116 /* ctx accesses must be at a fixed offset, so that we can 1117 1117 * determine what type of data were returned. 1118 1118 */ 1119 - if (!tnum_is_const(reg->var_off)) { 1119 + if (reg->off) { 1120 + verbose("dereference of modified ctx ptr R%d off=%d+%d, ctx+const is allowed, ctx+const+const is not\n", 1121 + regno, reg->off, off - reg->off); 1122 + return -EACCES; 1123 + } 1124 + if (!tnum_is_const(reg->var_off) || reg->var_off.value) { 1120 1125 char tn_buf[48]; 1121 1126 1122 1127 tnum_strn(tn_buf, sizeof(tn_buf), reg->var_off); ··· 1129 1124 tn_buf, off, size); 1130 1125 return -EACCES; 1131 1126 } 1132 - off += reg->var_off.value; 1133 1127 err = check_ctx_access(env, insn_idx, off, size, t, &reg_type); 1134 1128 if (!err && t == BPF_READ && value_regno >= 0) { 1135 1129 /* ctx access returns either a scalar, or a ··· 2430 2426 } 2431 2427 2432 2428 static void find_good_pkt_pointers(struct bpf_verifier_state *state, 2433 - struct bpf_reg_state *dst_reg) 2429 + struct bpf_reg_state *dst_reg, 2430 + bool range_right_open) 2434 2431 { 2435 2432 struct bpf_reg_state *regs = state->regs, *reg; 2433 + u16 new_range; 2436 2434 int i; 2437 2435 2438 - if (dst_reg->off < 0) 2436 + if (dst_reg->off < 0 || 2437 + (dst_reg->off == 0 && range_right_open)) 2439 2438 /* This doesn't give us any range */ 2440 2439 return; 2441 2440 ··· 2449 2442 */ 2450 2443 return; 2451 2444 2452 - /* LLVM can generate four kind of checks: 2445 + new_range = dst_reg->off; 2446 + if (range_right_open) 2447 + new_range--; 2448 + 2449 + /* Examples for register markings: 2453 2450 * 2454 - * Type 1/2: 2451 + * pkt_data in dst register: 2455 2452 * 2456 2453 * r2 = r3; 2457 2454 * r2 += 8; ··· 2472 2461 * r2=pkt(id=n,off=8,r=0) 2473 2462 * r3=pkt(id=n,off=0,r=0) 2474 2463 * 2475 - * Type 3/4: 2464 + * pkt_data in src register: 2476 2465 * 2477 2466 * r2 = r3; 2478 2467 * r2 += 8; ··· 2490 2479 * r3=pkt(id=n,off=0,r=0) 2491 2480 * 2492 2481 * Find register r3 and mark its range as r3=pkt(id=n,off=0,r=8) 2493 - * so that range of bytes [r3, r3 + 8) is safe to access. 2482 + * or r3=pkt(id=n,off=0,r=8-1), so that range of bytes [r3, r3 + 8) 2483 + * and [r3, r3 + 8-1) respectively is safe to access depending on 2484 + * the check. 2494 2485 */ 2495 2486 2496 2487 /* If our ids match, then we must have the same max_value. And we ··· 2503 2490 for (i = 0; i < MAX_BPF_REG; i++) 2504 2491 if (regs[i].type == PTR_TO_PACKET && regs[i].id == dst_reg->id) 2505 2492 /* keep the maximum range already checked */ 2506 - regs[i].range = max_t(u16, regs[i].range, dst_reg->off); 2493 + regs[i].range = max(regs[i].range, new_range); 2507 2494 2508 2495 for (i = 0; i < MAX_BPF_STACK; i += BPF_REG_SIZE) { 2509 2496 if (state->stack_slot_type[i] != STACK_SPILL) 2510 2497 continue; 2511 2498 reg = &state->spilled_regs[i / BPF_REG_SIZE]; 2512 2499 if (reg->type == PTR_TO_PACKET && reg->id == dst_reg->id) 2513 - reg->range = max_t(u16, reg->range, dst_reg->off); 2500 + reg->range = max(reg->range, new_range); 2514 2501 } 2515 2502 } 2516 2503 ··· 2874 2861 } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGT && 2875 2862 dst_reg->type == PTR_TO_PACKET && 2876 2863 regs[insn->src_reg].type == PTR_TO_PACKET_END) { 2877 - find_good_pkt_pointers(this_branch, dst_reg); 2864 + /* pkt_data' > pkt_end */ 2865 + find_good_pkt_pointers(this_branch, dst_reg, false); 2866 + } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGT && 2867 + dst_reg->type == PTR_TO_PACKET_END && 2868 + regs[insn->src_reg].type == PTR_TO_PACKET) { 2869 + /* pkt_end > pkt_data' */ 2870 + find_good_pkt_pointers(other_branch, &regs[insn->src_reg], true); 2878 2871 } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLT && 2879 2872 dst_reg->type == PTR_TO_PACKET && 2880 2873 regs[insn->src_reg].type == PTR_TO_PACKET_END) { 2881 - find_good_pkt_pointers(other_branch, dst_reg); 2874 + /* pkt_data' < pkt_end */ 2875 + find_good_pkt_pointers(other_branch, dst_reg, true); 2876 + } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLT && 2877 + dst_reg->type == PTR_TO_PACKET_END && 2878 + regs[insn->src_reg].type == PTR_TO_PACKET) { 2879 + /* pkt_end < pkt_data' */ 2880 + find_good_pkt_pointers(this_branch, &regs[insn->src_reg], false); 2881 + } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGE && 2882 + dst_reg->type == PTR_TO_PACKET && 2883 + regs[insn->src_reg].type == PTR_TO_PACKET_END) { 2884 + /* pkt_data' >= pkt_end */ 2885 + find_good_pkt_pointers(this_branch, dst_reg, true); 2882 2886 } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JGE && 2883 2887 dst_reg->type == PTR_TO_PACKET_END && 2884 2888 regs[insn->src_reg].type == PTR_TO_PACKET) { 2885 - find_good_pkt_pointers(other_branch, &regs[insn->src_reg]); 2889 + /* pkt_end >= pkt_data' */ 2890 + find_good_pkt_pointers(other_branch, &regs[insn->src_reg], false); 2891 + } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLE && 2892 + dst_reg->type == PTR_TO_PACKET && 2893 + regs[insn->src_reg].type == PTR_TO_PACKET_END) { 2894 + /* pkt_data' <= pkt_end */ 2895 + find_good_pkt_pointers(other_branch, dst_reg, false); 2886 2896 } else if (BPF_SRC(insn->code) == BPF_X && opcode == BPF_JLE && 2887 2897 dst_reg->type == PTR_TO_PACKET_END && 2888 2898 regs[insn->src_reg].type == PTR_TO_PACKET) { 2889 - find_good_pkt_pointers(this_branch, &regs[insn->src_reg]); 2899 + /* pkt_end <= pkt_data' */ 2900 + find_good_pkt_pointers(this_branch, &regs[insn->src_reg], true); 2890 2901 } else if (is_pointer_value(env, insn->dst_reg)) { 2891 2902 verbose("R%d pointer comparison prohibited\n", insn->dst_reg); 2892 2903 return -EACCES;
+1 -1
lib/ts_fsm.c
··· 11 11 * ========================================================================== 12 12 * 13 13 * A finite state machine consists of n states (struct ts_fsm_token) 14 - * representing the pattern as a finite automation. The data is read 14 + * representing the pattern as a finite automaton. The data is read 15 15 * sequentially on an octet basis. Every state token specifies the number 16 16 * of recurrences and the type of value accepted which can be either a 17 17 * specific character or ctype based set of characters. The available
+1 -1
lib/ts_kmp.c
··· 27 27 * 28 28 * [1] Cormen, Leiserson, Rivest, Stein 29 29 * Introdcution to Algorithms, 2nd Edition, MIT Press 30 - * [2] See finite automation theory 30 + * [2] See finite automaton theory 31 31 */ 32 32 33 33 #include <linux/module.h>
-15
mm/memcontrol.c
··· 5828 5828 if (!mem_cgroup_sockets_enabled) 5829 5829 return; 5830 5830 5831 - /* 5832 - * Socket cloning can throw us here with sk_memcg already 5833 - * filled. It won't however, necessarily happen from 5834 - * process context. So the test for root memcg given 5835 - * the current task's memcg won't help us in this case. 5836 - * 5837 - * Respecting the original socket's memcg is a better 5838 - * decision in this case. 5839 - */ 5840 - if (sk->sk_memcg) { 5841 - BUG_ON(mem_cgroup_is_root(sk->sk_memcg)); 5842 - css_get(&sk->sk_memcg->css); 5843 - return; 5844 - } 5845 - 5846 5831 rcu_read_lock(); 5847 5832 memcg = mem_cgroup_from_task(current); 5848 5833 if (memcg == root_mem_cgroup)
+10 -5
mm/percpu.c
··· 1329 1329 * @gfp: allocation flags 1330 1330 * 1331 1331 * Allocate percpu area of @size bytes aligned at @align. If @gfp doesn't 1332 - * contain %GFP_KERNEL, the allocation is atomic. 1332 + * contain %GFP_KERNEL, the allocation is atomic. If @gfp has __GFP_NOWARN 1333 + * then no warning will be triggered on invalid or failed allocation 1334 + * requests. 1333 1335 * 1334 1336 * RETURNS: 1335 1337 * Percpu pointer to the allocated area on success, NULL on failure. ··· 1339 1337 static void __percpu *pcpu_alloc(size_t size, size_t align, bool reserved, 1340 1338 gfp_t gfp) 1341 1339 { 1340 + bool is_atomic = (gfp & GFP_KERNEL) != GFP_KERNEL; 1341 + bool do_warn = !(gfp & __GFP_NOWARN); 1342 1342 static int warn_limit = 10; 1343 1343 struct pcpu_chunk *chunk; 1344 1344 const char *err; 1345 - bool is_atomic = (gfp & GFP_KERNEL) != GFP_KERNEL; 1346 1345 int slot, off, cpu, ret; 1347 1346 unsigned long flags; 1348 1347 void __percpu *ptr; ··· 1364 1361 1365 1362 if (unlikely(!size || size > PCPU_MIN_UNIT_SIZE || align > PAGE_SIZE || 1366 1363 !is_power_of_2(align))) { 1367 - WARN(true, "illegal size (%zu) or align (%zu) for percpu allocation\n", 1364 + WARN(do_warn, "illegal size (%zu) or align (%zu) for percpu allocation\n", 1368 1365 size, align); 1369 1366 return NULL; 1370 1367 } ··· 1485 1482 fail: 1486 1483 trace_percpu_alloc_percpu_fail(reserved, is_atomic, size, align); 1487 1484 1488 - if (!is_atomic && warn_limit) { 1485 + if (!is_atomic && do_warn && warn_limit) { 1489 1486 pr_warn("allocation failed, size=%zu align=%zu atomic=%d, %s\n", 1490 1487 size, align, is_atomic, err); 1491 1488 dump_stack(); ··· 1510 1507 * 1511 1508 * Allocate zero-filled percpu area of @size bytes aligned at @align. If 1512 1509 * @gfp doesn't contain %GFP_KERNEL, the allocation doesn't block and can 1513 - * be called from any context but is a lot more likely to fail. 1510 + * be called from any context but is a lot more likely to fail. If @gfp 1511 + * has __GFP_NOWARN then no warning will be triggered on invalid or failed 1512 + * allocation requests. 1514 1513 * 1515 1514 * RETURNS: 1516 1515 * Percpu pointer to the allocated area on success, NULL on failure.
+1 -1
net/bridge/br_netlink.c
··· 573 573 } 574 574 *vinfo_last = NULL; 575 575 576 - return 0; 576 + return err; 577 577 } 578 578 579 579 return br_vlan_info(br, p, cmd, vinfo_curr);
+16 -4
net/can/af_can.c
··· 78 78 static struct kmem_cache *rcv_cache __read_mostly; 79 79 80 80 /* table of registered CAN protocols */ 81 - static const struct can_proto *proto_tab[CAN_NPROTO] __read_mostly; 81 + static const struct can_proto __rcu *proto_tab[CAN_NPROTO] __read_mostly; 82 82 static DEFINE_MUTEX(proto_tab_lock); 83 83 84 84 static atomic_t skbcounter = ATOMIC_INIT(0); ··· 788 788 789 789 mutex_lock(&proto_tab_lock); 790 790 791 - if (proto_tab[proto]) { 791 + if (rcu_access_pointer(proto_tab[proto])) { 792 792 pr_err("can: protocol %d already registered\n", proto); 793 793 err = -EBUSY; 794 794 } else ··· 812 812 int proto = cp->protocol; 813 813 814 814 mutex_lock(&proto_tab_lock); 815 - BUG_ON(proto_tab[proto] != cp); 815 + BUG_ON(rcu_access_pointer(proto_tab[proto]) != cp); 816 816 RCU_INIT_POINTER(proto_tab[proto], NULL); 817 817 mutex_unlock(&proto_tab_lock); 818 818 ··· 875 875 spin_lock_init(&net->can.can_rcvlists_lock); 876 876 net->can.can_rx_alldev_list = 877 877 kzalloc(sizeof(struct dev_rcv_lists), GFP_KERNEL); 878 - 878 + if (!net->can.can_rx_alldev_list) 879 + goto out; 879 880 net->can.can_stats = kzalloc(sizeof(struct s_stats), GFP_KERNEL); 881 + if (!net->can.can_stats) 882 + goto out_free_alldev_list; 880 883 net->can.can_pstats = kzalloc(sizeof(struct s_pstats), GFP_KERNEL); 884 + if (!net->can.can_pstats) 885 + goto out_free_can_stats; 881 886 882 887 if (IS_ENABLED(CONFIG_PROC_FS)) { 883 888 /* the statistics are updated every second (timer triggered) */ ··· 897 892 } 898 893 899 894 return 0; 895 + 896 + out_free_can_stats: 897 + kfree(net->can.can_stats); 898 + out_free_alldev_list: 899 + kfree(net->can.can_rx_alldev_list); 900 + out: 901 + return -ENOMEM; 900 902 } 901 903 902 904 static void can_pernet_exit(struct net *net)
+3 -2
net/can/bcm.c
··· 1493 1493 static int bcm_release(struct socket *sock) 1494 1494 { 1495 1495 struct sock *sk = sock->sk; 1496 - struct net *net = sock_net(sk); 1496 + struct net *net; 1497 1497 struct bcm_sock *bo; 1498 1498 struct bcm_op *op, *next; 1499 1499 1500 - if (sk == NULL) 1500 + if (!sk) 1501 1501 return 0; 1502 1502 1503 + net = sock_net(sk); 1503 1504 bo = bcm_sk(sk); 1504 1505 1505 1506 /* remove bcm_ops, timer, rx_unregister(), etc. */
+3 -3
net/core/dev.c
··· 1147 1147 return ret; 1148 1148 } 1149 1149 1150 - static int dev_get_valid_name(struct net *net, 1151 - struct net_device *dev, 1152 - const char *name) 1150 + int dev_get_valid_name(struct net *net, struct net_device *dev, 1151 + const char *name) 1153 1152 { 1154 1153 BUG_ON(!net); 1155 1154 ··· 1164 1165 1165 1166 return 0; 1166 1167 } 1168 + EXPORT_SYMBOL(dev_get_valid_name); 1167 1169 1168 1170 /** 1169 1171 * dev_change_name - change name of a device
+12 -1
net/core/dev_ioctl.c
··· 303 303 case SIOCSIFTXQLEN: 304 304 if (ifr->ifr_qlen < 0) 305 305 return -EINVAL; 306 - dev->tx_queue_len = ifr->ifr_qlen; 306 + if (dev->tx_queue_len ^ ifr->ifr_qlen) { 307 + unsigned int orig_len = dev->tx_queue_len; 308 + 309 + dev->tx_queue_len = ifr->ifr_qlen; 310 + err = call_netdevice_notifiers( 311 + NETDEV_CHANGE_TX_QUEUE_LEN, dev); 312 + err = notifier_to_errno(err); 313 + if (err) { 314 + dev->tx_queue_len = orig_len; 315 + return err; 316 + } 317 + } 307 318 return 0; 308 319 309 320 case SIOCSIFNAME:
+2 -3
net/core/ethtool.c
··· 436 436 EXPORT_SYMBOL(ethtool_convert_link_mode_to_legacy_u32); 437 437 438 438 /* return false if legacy contained non-0 deprecated fields 439 - * transceiver/maxtxpkt/maxrxpkt. rest of ksettings always updated 439 + * maxtxpkt/maxrxpkt. rest of ksettings always updated 440 440 */ 441 441 static bool 442 442 convert_legacy_settings_to_link_ksettings( ··· 451 451 * deprecated legacy fields, and they should not use 452 452 * %ETHTOOL_GLINKSETTINGS/%ETHTOOL_SLINKSETTINGS 453 453 */ 454 - if (legacy_settings->transceiver || 455 - legacy_settings->maxtxpkt || 454 + if (legacy_settings->maxtxpkt || 456 455 legacy_settings->maxrxpkt) 457 456 retval = false; 458 457
+16 -15
net/core/filter.c
··· 1839 1839 .arg2_type = ARG_ANYTHING, 1840 1840 }; 1841 1841 1842 - BPF_CALL_3(bpf_sk_redirect_map, struct bpf_map *, map, u32, key, u64, flags) 1842 + BPF_CALL_4(bpf_sk_redirect_map, struct sk_buff *, skb, 1843 + struct bpf_map *, map, u32, key, u64, flags) 1843 1844 { 1844 - struct redirect_info *ri = this_cpu_ptr(&redirect_info); 1845 + struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); 1845 1846 1846 1847 if (unlikely(flags)) 1847 1848 return SK_ABORTED; 1848 1849 1849 - ri->ifindex = key; 1850 - ri->flags = flags; 1851 - ri->map = map; 1850 + tcb->bpf.key = key; 1851 + tcb->bpf.flags = flags; 1852 + tcb->bpf.map = map; 1852 1853 1853 1854 return SK_REDIRECT; 1854 1855 } 1855 1856 1856 - struct sock *do_sk_redirect_map(void) 1857 + struct sock *do_sk_redirect_map(struct sk_buff *skb) 1857 1858 { 1858 - struct redirect_info *ri = this_cpu_ptr(&redirect_info); 1859 + struct tcp_skb_cb *tcb = TCP_SKB_CB(skb); 1859 1860 struct sock *sk = NULL; 1860 1861 1861 - if (ri->map) { 1862 - sk = __sock_map_lookup_elem(ri->map, ri->ifindex); 1862 + if (tcb->bpf.map) { 1863 + sk = __sock_map_lookup_elem(tcb->bpf.map, tcb->bpf.key); 1863 1864 1864 - ri->ifindex = 0; 1865 - ri->map = NULL; 1866 - /* we do not clear flags for future lookup */ 1865 + tcb->bpf.key = 0; 1866 + tcb->bpf.map = NULL; 1867 1867 } 1868 1868 1869 1869 return sk; ··· 1873 1873 .func = bpf_sk_redirect_map, 1874 1874 .gpl_only = false, 1875 1875 .ret_type = RET_INTEGER, 1876 - .arg1_type = ARG_CONST_MAP_PTR, 1877 - .arg2_type = ARG_ANYTHING, 1876 + .arg1_type = ARG_PTR_TO_CTX, 1877 + .arg2_type = ARG_CONST_MAP_PTR, 1878 1878 .arg3_type = ARG_ANYTHING, 1879 + .arg4_type = ARG_ANYTHING, 1879 1880 }; 1880 1881 1881 1882 BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb) ··· 3684 3683 { 3685 3684 if (type == BPF_WRITE) { 3686 3685 switch (off) { 3687 - case bpf_ctx_range(struct __sk_buff, mark): 3688 3686 case bpf_ctx_range(struct __sk_buff, tc_index): 3689 3687 case bpf_ctx_range(struct __sk_buff, priority): 3690 3688 break; ··· 3693 3693 } 3694 3694 3695 3695 switch (off) { 3696 + case bpf_ctx_range(struct __sk_buff, mark): 3696 3697 case bpf_ctx_range(struct __sk_buff, tc_classid): 3697 3698 return false; 3698 3699 case bpf_ctx_range(struct __sk_buff, data):
+10 -3
net/core/rtnetlink.c
··· 1483 1483 [IFLA_LINKINFO] = { .type = NLA_NESTED }, 1484 1484 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 1485 1485 [IFLA_NET_NS_FD] = { .type = NLA_U32 }, 1486 - [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, 1486 + /* IFLA_IFALIAS is a string, but policy is set to NLA_BINARY to 1487 + * allow 0-length string (needed to remove an alias). 1488 + */ 1489 + [IFLA_IFALIAS] = { .type = NLA_BINARY, .len = IFALIASZ - 1 }, 1487 1490 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, 1488 1491 [IFLA_VF_PORTS] = { .type = NLA_NESTED }, 1489 1492 [IFLA_PORT_SELF] = { .type = NLA_NESTED }, ··· 2096 2093 dev->tx_queue_len = orig_len; 2097 2094 goto errout; 2098 2095 } 2099 - status |= DO_SETLINK_NOTIFY; 2096 + status |= DO_SETLINK_MODIFIED; 2100 2097 } 2101 2098 } 2102 2099 ··· 2251 2248 2252 2249 errout: 2253 2250 if (status & DO_SETLINK_MODIFIED) { 2254 - if (status & DO_SETLINK_NOTIFY) 2251 + if ((status & DO_SETLINK_NOTIFY) == DO_SETLINK_NOTIFY) 2255 2252 netdev_state_change(dev); 2256 2253 2257 2254 if (err < 0) ··· 4282 4279 4283 4280 switch (event) { 4284 4281 case NETDEV_REBOOT: 4282 + case NETDEV_CHANGEMTU: 4285 4283 case NETDEV_CHANGEADDR: 4286 4284 case NETDEV_CHANGENAME: 4287 4285 case NETDEV_FEAT_CHANGE: 4288 4286 case NETDEV_BONDING_FAILOVER: 4287 + case NETDEV_POST_TYPE_CHANGE: 4289 4288 case NETDEV_NOTIFY_PEERS: 4289 + case NETDEV_CHANGEUPPER: 4290 4290 case NETDEV_RESEND_IGMP: 4291 4291 case NETDEV_CHANGEINFODATA: 4292 + case NETDEV_CHANGE_TX_QUEUE_LEN: 4292 4293 rtmsg_ifinfo_event(RTM_NEWLINK, dev, 0, rtnl_get_event(event), 4293 4294 GFP_KERNEL); 4294 4295 break;
+5 -1
net/core/skbuff.c
··· 1124 1124 1125 1125 err = __zerocopy_sg_from_iter(sk, skb, &msg->msg_iter, len); 1126 1126 if (err == -EFAULT || (err == -EMSGSIZE && skb->len == orig_len)) { 1127 + struct sock *save_sk = skb->sk; 1128 + 1127 1129 /* Streams do not free skb on error. Reset to prev state. */ 1128 1130 msg->msg_iter = orig_iter; 1131 + skb->sk = sk; 1129 1132 ___pskb_trim(skb, orig_len); 1133 + skb->sk = save_sk; 1130 1134 return err; 1131 1135 } 1132 1136 ··· 1900 1896 } 1901 1897 1902 1898 /* If we need update frag list, we are in troubles. 1903 - * Certainly, it possible to add an offset to skb data, 1899 + * Certainly, it is possible to add an offset to skb data, 1904 1900 * but taking into account that pulling is expected to 1905 1901 * be very rare operation, it is worth to fight against 1906 1902 * further bloating skb head and crucify ourselves here instead.
+5 -3
net/core/sock.c
··· 1677 1677 newsk->sk_dst_pending_confirm = 0; 1678 1678 newsk->sk_wmem_queued = 0; 1679 1679 newsk->sk_forward_alloc = 0; 1680 + 1681 + /* sk->sk_memcg will be populated at accept() time */ 1682 + newsk->sk_memcg = NULL; 1683 + 1680 1684 atomic_set(&newsk->sk_drops, 0); 1681 1685 newsk->sk_send_head = NULL; 1682 1686 newsk->sk_userlocks = sk->sk_userlocks & ~SOCK_BINDPORT_LOCK; 1683 1687 atomic_set(&newsk->sk_zckey, 0); 1684 1688 1685 1689 sock_reset_flag(newsk, SOCK_DONE); 1690 + cgroup_sk_alloc(&newsk->sk_cgrp_data); 1686 1691 1687 1692 rcu_read_lock(); 1688 1693 filter = rcu_dereference(sk->sk_filter); ··· 1718 1713 newsk->sk_priority = 0; 1719 1714 newsk->sk_incoming_cpu = raw_smp_processor_id(); 1720 1715 atomic64_set(&newsk->sk_cookie, 0); 1721 - 1722 - mem_cgroup_sk_alloc(newsk); 1723 - cgroup_sk_alloc(&newsk->sk_cgrp_data); 1724 1716 1725 1717 /* 1726 1718 * Before updating sk_refcnt, we must commit prior changes to memory
+9 -3
net/core/sock_reuseport.c
··· 36 36 * soft irq of receive path or setsockopt from process context 37 37 */ 38 38 spin_lock_bh(&reuseport_lock); 39 - WARN_ONCE(rcu_dereference_protected(sk->sk_reuseport_cb, 40 - lockdep_is_held(&reuseport_lock)), 41 - "multiple allocations for the same socket"); 39 + 40 + /* Allocation attempts can occur concurrently via the setsockopt path 41 + * and the bind/hash path. Nothing to do when we lose the race. 42 + */ 43 + if (rcu_dereference_protected(sk->sk_reuseport_cb, 44 + lockdep_is_held(&reuseport_lock))) 45 + goto out; 46 + 42 47 reuse = __reuseport_alloc(INIT_SOCKS); 43 48 if (!reuse) { 44 49 spin_unlock_bh(&reuseport_lock); ··· 54 49 reuse->num_socks = 1; 55 50 rcu_assign_pointer(sk->sk_reuseport_cb, reuse); 56 51 52 + out: 57 53 spin_unlock_bh(&reuseport_lock); 58 54 59 55 return 0;
+8 -5
net/dccp/ipv4.c
··· 414 414 sk_daddr_set(newsk, ireq->ir_rmt_addr); 415 415 sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); 416 416 newinet->inet_saddr = ireq->ir_loc_addr; 417 - newinet->inet_opt = ireq->opt; 418 - ireq->opt = NULL; 417 + RCU_INIT_POINTER(newinet->inet_opt, rcu_dereference(ireq->ireq_opt)); 419 418 newinet->mc_index = inet_iif(skb); 420 419 newinet->mc_ttl = ip_hdr(skb)->ttl; 421 420 newinet->inet_id = jiffies; ··· 429 430 if (__inet_inherit_port(sk, newsk) < 0) 430 431 goto put_and_exit; 431 432 *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); 432 - 433 + if (*own_req) 434 + ireq->ireq_opt = NULL; 435 + else 436 + newinet->inet_opt = NULL; 433 437 return newsk; 434 438 435 439 exit_overflow: ··· 443 441 __NET_INC_STATS(sock_net(sk), LINUX_MIB_LISTENDROPS); 444 442 return NULL; 445 443 put_and_exit: 444 + newinet->inet_opt = NULL; 446 445 inet_csk_prepare_forced_close(newsk); 447 446 dccp_done(newsk); 448 447 goto exit; ··· 495 492 ireq->ir_rmt_addr); 496 493 err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, 497 494 ireq->ir_rmt_addr, 498 - ireq->opt); 495 + rcu_dereference(ireq->ireq_opt)); 499 496 err = net_xmit_eval(err); 500 497 } 501 498 ··· 551 548 static void dccp_v4_reqsk_destructor(struct request_sock *req) 552 549 { 553 550 dccp_feat_list_purge(&dccp_rsk(req)->dreq_featneg); 554 - kfree(inet_rsk(req)->opt); 551 + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); 555 552 } 556 553 557 554 void dccp_syn_ack_timeout(const struct request_sock *req)
+3 -5
net/ipv4/Kconfig
··· 70 70 address into account. Furthermore, the TOS (Type-Of-Service) field 71 71 of the packet can be used for routing decisions as well. 72 72 73 - If you are interested in this, please see the preliminary 74 - documentation at <http://www.compendium.com.ar/policy-routing.txt> 75 - and <ftp://post.tepkom.ru/pub/vol2/Linux/docs/advanced-routing.tex>. 76 - You will need supporting software from 77 - <ftp://ftp.tux.org/pub/net/ip-routing/>. 73 + If you need more information, see the Linux Advanced 74 + Routing and Traffic Control documentation at 75 + <http://lartc.org/howto/lartc.rpdb.html> 78 76 79 77 If unsure, say N. 80 78
+7 -17
net/ipv4/cipso_ipv4.c
··· 1951 1951 buf = NULL; 1952 1952 1953 1953 req_inet = inet_rsk(req); 1954 - opt = xchg(&req_inet->opt, opt); 1954 + opt = xchg((__force struct ip_options_rcu **)&req_inet->ireq_opt, opt); 1955 1955 if (opt) 1956 1956 kfree_rcu(opt, rcu); 1957 1957 ··· 1973 1973 * values on failure. 1974 1974 * 1975 1975 */ 1976 - static int cipso_v4_delopt(struct ip_options_rcu **opt_ptr) 1976 + static int cipso_v4_delopt(struct ip_options_rcu __rcu **opt_ptr) 1977 1977 { 1978 + struct ip_options_rcu *opt = rcu_dereference_protected(*opt_ptr, 1); 1978 1979 int hdr_delta = 0; 1979 - struct ip_options_rcu *opt = *opt_ptr; 1980 1980 1981 + if (!opt || opt->opt.cipso == 0) 1982 + return 0; 1981 1983 if (opt->opt.srr || opt->opt.rr || opt->opt.ts || opt->opt.router_alert) { 1982 1984 u8 cipso_len; 1983 1985 u8 cipso_off; ··· 2041 2039 */ 2042 2040 void cipso_v4_sock_delattr(struct sock *sk) 2043 2041 { 2044 - int hdr_delta; 2045 - struct ip_options_rcu *opt; 2046 2042 struct inet_sock *sk_inet; 2043 + int hdr_delta; 2047 2044 2048 2045 sk_inet = inet_sk(sk); 2049 - opt = rcu_dereference_protected(sk_inet->inet_opt, 1); 2050 - if (!opt || opt->opt.cipso == 0) 2051 - return; 2052 2046 2053 2047 hdr_delta = cipso_v4_delopt(&sk_inet->inet_opt); 2054 2048 if (sk_inet->is_icsk && hdr_delta > 0) { ··· 2064 2066 */ 2065 2067 void cipso_v4_req_delattr(struct request_sock *req) 2066 2068 { 2067 - struct ip_options_rcu *opt; 2068 - struct inet_request_sock *req_inet; 2069 - 2070 - req_inet = inet_rsk(req); 2071 - opt = req_inet->opt; 2072 - if (!opt || opt->opt.cipso == 0) 2073 - return; 2074 - 2075 - cipso_v4_delopt(&req_inet->opt); 2069 + cipso_v4_delopt(&inet_rsk(req)->ireq_opt); 2076 2070 } 2077 2071 2078 2072 /**
+4 -5
net/ipv4/inet_connection_sock.c
··· 475 475 } 476 476 spin_unlock_bh(&queue->fastopenq.lock); 477 477 } 478 + mem_cgroup_sk_alloc(newsk); 478 479 out: 479 480 release_sock(sk); 480 481 if (req) ··· 540 539 { 541 540 const struct inet_request_sock *ireq = inet_rsk(req); 542 541 struct net *net = read_pnet(&ireq->ireq_net); 543 - struct ip_options_rcu *opt = ireq->opt; 542 + struct ip_options_rcu *opt; 544 543 struct rtable *rt; 545 544 545 + opt = rcu_dereference(ireq->ireq_opt); 546 546 flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, 547 547 RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, 548 548 sk->sk_protocol, inet_sk_flowi_flags(sk), ··· 577 575 struct flowi4 *fl4; 578 576 struct rtable *rt; 579 577 578 + opt = rcu_dereference(ireq->ireq_opt); 580 579 fl4 = &newinet->cork.fl.u.ip4; 581 580 582 - rcu_read_lock(); 583 - opt = rcu_dereference(newinet->inet_opt); 584 581 flowi4_init_output(fl4, ireq->ir_iif, ireq->ir_mark, 585 582 RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, 586 583 sk->sk_protocol, inet_sk_flowi_flags(sk), ··· 592 591 goto no_route; 593 592 if (opt && opt->opt.is_strictroute && rt->rt_uses_gateway) 594 593 goto route_err; 595 - rcu_read_unlock(); 596 594 return &rt->dst; 597 595 598 596 route_err: 599 597 ip_rt_put(rt); 600 598 no_route: 601 - rcu_read_unlock(); 602 599 __IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); 603 600 return NULL; 604 601 }
+1 -4
net/ipv4/inet_hashtables.c
··· 456 456 return reuseport_add_sock(sk, sk2); 457 457 } 458 458 459 - /* Initial allocation may have already happened via setsockopt */ 460 - if (!rcu_access_pointer(sk->sk_reuseport_cb)) 461 - return reuseport_alloc(sk); 462 - return 0; 459 + return reuseport_alloc(sk); 463 460 } 464 461 465 462 int __inet_hash(struct sock *sk, struct sock *osk)
+1 -1
net/ipv4/syncookies.c
··· 355 355 /* We throwed the options of the initial SYN away, so we hope 356 356 * the ACK carries the same options again (see RFC1122 4.2.3.8) 357 357 */ 358 - ireq->opt = tcp_v4_save_options(sock_net(sk), skb); 358 + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(sock_net(sk), skb)); 359 359 360 360 if (security_inet_conn_request(sk, skb, req)) { 361 361 reqsk_free(req);
+1 -1
net/ipv4/tcp_input.c
··· 6196 6196 struct inet_request_sock *ireq = inet_rsk(req); 6197 6197 6198 6198 kmemcheck_annotate_bitfield(ireq, flags); 6199 - ireq->opt = NULL; 6199 + ireq->ireq_opt = NULL; 6200 6200 #if IS_ENABLED(CONFIG_IPV6) 6201 6201 ireq->pktopts = NULL; 6202 6202 #endif
+13 -9
net/ipv4/tcp_ipv4.c
··· 877 877 878 878 err = ip_build_and_send_pkt(skb, sk, ireq->ir_loc_addr, 879 879 ireq->ir_rmt_addr, 880 - ireq->opt); 880 + rcu_dereference(ireq->ireq_opt)); 881 881 err = net_xmit_eval(err); 882 882 } 883 883 ··· 889 889 */ 890 890 static void tcp_v4_reqsk_destructor(struct request_sock *req) 891 891 { 892 - kfree(inet_rsk(req)->opt); 892 + kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1)); 893 893 } 894 894 895 895 #ifdef CONFIG_TCP_MD5SIG ··· 1265 1265 struct sk_buff *skb) 1266 1266 { 1267 1267 struct inet_request_sock *ireq = inet_rsk(req); 1268 + struct net *net = sock_net(sk_listener); 1268 1269 1269 1270 sk_rcv_saddr_set(req_to_sk(req), ip_hdr(skb)->daddr); 1270 1271 sk_daddr_set(req_to_sk(req), ip_hdr(skb)->saddr); 1271 - ireq->opt = tcp_v4_save_options(sock_net(sk_listener), skb); 1272 + RCU_INIT_POINTER(ireq->ireq_opt, tcp_v4_save_options(net, skb)); 1272 1273 } 1273 1274 1274 1275 static struct dst_entry *tcp_v4_route_req(const struct sock *sk, ··· 1356 1355 sk_daddr_set(newsk, ireq->ir_rmt_addr); 1357 1356 sk_rcv_saddr_set(newsk, ireq->ir_loc_addr); 1358 1357 newsk->sk_bound_dev_if = ireq->ir_iif; 1359 - newinet->inet_saddr = ireq->ir_loc_addr; 1360 - inet_opt = ireq->opt; 1361 - rcu_assign_pointer(newinet->inet_opt, inet_opt); 1362 - ireq->opt = NULL; 1358 + newinet->inet_saddr = ireq->ir_loc_addr; 1359 + inet_opt = rcu_dereference(ireq->ireq_opt); 1360 + RCU_INIT_POINTER(newinet->inet_opt, inet_opt); 1363 1361 newinet->mc_index = inet_iif(skb); 1364 1362 newinet->mc_ttl = ip_hdr(skb)->ttl; 1365 1363 newinet->rcv_tos = ip_hdr(skb)->tos; ··· 1403 1403 if (__inet_inherit_port(sk, newsk) < 0) 1404 1404 goto put_and_exit; 1405 1405 *own_req = inet_ehash_nolisten(newsk, req_to_sk(req_unhash)); 1406 - if (*own_req) 1406 + if (likely(*own_req)) { 1407 1407 tcp_move_syn(newtp, req); 1408 - 1408 + ireq->ireq_opt = NULL; 1409 + } else { 1410 + newinet->inet_opt = NULL; 1411 + } 1409 1412 return newsk; 1410 1413 1411 1414 exit_overflow: ··· 1419 1416 tcp_listendrop(sk); 1420 1417 return NULL; 1421 1418 put_and_exit: 1419 + newinet->inet_opt = NULL; 1422 1420 inet_csk_prepare_forced_close(newsk); 1423 1421 tcp_done(newsk); 1424 1422 goto exit;
+3 -6
net/ipv4/udp.c
··· 231 231 } 232 232 } 233 233 234 - /* Initial allocation may have already happened via setsockopt */ 235 - if (!rcu_access_pointer(sk->sk_reuseport_cb)) 236 - return reuseport_alloc(sk); 237 - return 0; 234 + return reuseport_alloc(sk); 238 235 } 239 236 240 237 /** ··· 1058 1061 /* ... which is an evident application bug. --ANK */ 1059 1062 release_sock(sk); 1060 1063 1061 - net_dbg_ratelimited("cork app bug 2\n"); 1064 + net_dbg_ratelimited("socket already corked\n"); 1062 1065 err = -EINVAL; 1063 1066 goto out; 1064 1067 } ··· 1141 1144 if (unlikely(!up->pending)) { 1142 1145 release_sock(sk); 1143 1146 1144 - net_dbg_ratelimited("udp cork app bug 3\n"); 1147 + net_dbg_ratelimited("cork failed\n"); 1145 1148 return -EINVAL; 1146 1149 } 1147 1150
+1
net/ipv6/ip6_flowlabel.c
··· 315 315 } 316 316 opt_space->dst1opt = fopt->dst1opt; 317 317 opt_space->opt_flen = fopt->opt_flen; 318 + opt_space->tot_len = fopt->tot_len; 318 319 return opt_space; 319 320 } 320 321 EXPORT_SYMBOL_GPL(fl6_merge_options);
+2 -2
net/ipv6/ip6_output.c
··· 1161 1161 if (WARN_ON(v6_cork->opt)) 1162 1162 return -EINVAL; 1163 1163 1164 - v6_cork->opt = kzalloc(opt->tot_len, sk->sk_allocation); 1164 + v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation); 1165 1165 if (unlikely(!v6_cork->opt)) 1166 1166 return -ENOBUFS; 1167 1167 1168 - v6_cork->opt->tot_len = opt->tot_len; 1168 + v6_cork->opt->tot_len = sizeof(*opt); 1169 1169 v6_cork->opt->opt_flen = opt->opt_flen; 1170 1170 v6_cork->opt->opt_nflen = opt->opt_nflen; 1171 1171
+3
net/l2tp/l2tp_ppp.c
··· 988 988 session->name, cmd, arg); 989 989 990 990 sk = ps->sock; 991 + if (!sk) 992 + return -EBADR; 993 + 991 994 sock_hold(sk); 992 995 993 996 switch (cmd) {
+17 -4
net/mac80211/key.c
··· 4 4 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 5 5 * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net> 6 6 * Copyright 2013-2014 Intel Mobile Communications GmbH 7 - * Copyright 2015 Intel Deutschland GmbH 7 + * Copyright 2015-2017 Intel Deutschland GmbH 8 8 * 9 9 * This program is free software; you can redistribute it and/or modify 10 10 * it under the terms of the GNU General Public License version 2 as ··· 620 620 621 621 pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; 622 622 idx = key->conf.keyidx; 623 - key->local = sdata->local; 624 - key->sdata = sdata; 625 - key->sta = sta; 626 623 627 624 mutex_lock(&sdata->local->key_mtx); 628 625 ··· 629 632 old_key = key_mtx_dereference(sdata->local, sta->gtk[idx]); 630 633 else 631 634 old_key = key_mtx_dereference(sdata->local, sdata->keys[idx]); 635 + 636 + /* 637 + * Silently accept key re-installation without really installing the 638 + * new version of the key to avoid nonce reuse or replay issues. 639 + */ 640 + if (old_key && key->conf.keylen == old_key->conf.keylen && 641 + !memcmp(key->conf.key, old_key->conf.key, key->conf.keylen)) { 642 + ieee80211_key_free_unused(key); 643 + ret = 0; 644 + goto out; 645 + } 646 + 647 + key->local = sdata->local; 648 + key->sdata = sdata; 649 + key->sta = sta; 632 650 633 651 increment_tailroom_need_count(sdata); 634 652 ··· 660 648 ret = 0; 661 649 } 662 650 651 + out: 663 652 mutex_unlock(&sdata->local->key_mtx); 664 653 665 654 return ret;
+1
net/ncsi/internal.h
··· 286 286 struct work_struct work; /* For channel management */ 287 287 struct packet_type ptype; /* NCSI packet Rx handler */ 288 288 struct list_head node; /* Form NCSI device list */ 289 + #define NCSI_MAX_VLAN_VIDS 15 289 290 struct list_head vlan_vids; /* List of active VLAN IDs */ 290 291 }; 291 292
+1 -1
net/ncsi/ncsi-aen.c
··· 187 187 } ncsi_aen_handlers[] = { 188 188 { NCSI_PKT_AEN_LSC, 12, ncsi_aen_handler_lsc }, 189 189 { NCSI_PKT_AEN_CR, 4, ncsi_aen_handler_cr }, 190 - { NCSI_PKT_AEN_HNCDSC, 4, ncsi_aen_handler_hncdsc } 190 + { NCSI_PKT_AEN_HNCDSC, 8, ncsi_aen_handler_hncdsc } 191 191 }; 192 192 193 193 int ncsi_aen_handler(struct ncsi_dev_priv *ndp, struct sk_buff *skb)
+33 -19
net/ncsi/ncsi-manage.c
··· 189 189 struct ncsi_channel *nc = (struct ncsi_channel *)data; 190 190 struct ncsi_package *np = nc->package; 191 191 struct ncsi_dev_priv *ndp = np->ndp; 192 + struct ncsi_channel_mode *ncm; 192 193 struct ncsi_cmd_arg nca; 193 194 bool enabled, chained; 194 195 unsigned int monitor_state; ··· 203 202 monitor_state = nc->monitor.state; 204 203 spin_unlock_irqrestore(&nc->lock, flags); 205 204 206 - if (!enabled || chained) 205 + if (!enabled || chained) { 206 + ncsi_stop_channel_monitor(nc); 207 207 return; 208 + } 208 209 if (state != NCSI_CHANNEL_INACTIVE && 209 - state != NCSI_CHANNEL_ACTIVE) 210 + state != NCSI_CHANNEL_ACTIVE) { 211 + ncsi_stop_channel_monitor(nc); 210 212 return; 213 + } 211 214 212 215 switch (monitor_state) { 213 216 case NCSI_CHANNEL_MONITOR_START: ··· 222 217 nca.type = NCSI_PKT_CMD_GLS; 223 218 nca.req_flags = 0; 224 219 ret = ncsi_xmit_cmd(&nca); 225 - if (ret) { 220 + if (ret) 226 221 netdev_err(ndp->ndev.dev, "Error %d sending GLS\n", 227 222 ret); 228 - return; 229 - } 230 - 231 223 break; 232 224 case NCSI_CHANNEL_MONITOR_WAIT ... NCSI_CHANNEL_MONITOR_WAIT_MAX: 233 225 break; 234 226 default: 235 - if (!(ndp->flags & NCSI_DEV_HWA) && 236 - state == NCSI_CHANNEL_ACTIVE) { 227 + if (!(ndp->flags & NCSI_DEV_HWA)) { 237 228 ncsi_report_link(ndp, true); 238 229 ndp->flags |= NCSI_DEV_RESHUFFLE; 239 230 } 240 231 232 + ncsi_stop_channel_monitor(nc); 233 + 234 + ncm = &nc->modes[NCSI_MODE_LINK]; 241 235 spin_lock_irqsave(&nc->lock, flags); 242 236 nc->state = NCSI_CHANNEL_INVISIBLE; 237 + ncm->data[2] &= ~0x1; 243 238 spin_unlock_irqrestore(&nc->lock, flags); 244 239 245 240 spin_lock_irqsave(&ndp->lock, flags); 246 - nc->state = NCSI_CHANNEL_INACTIVE; 241 + nc->state = NCSI_CHANNEL_ACTIVE; 247 242 list_add_tail_rcu(&nc->link, &ndp->channel_queue); 248 243 spin_unlock_irqrestore(&ndp->lock, flags); 249 244 ncsi_process_next_channel(ndp); ··· 737 732 if (index < 0) { 738 733 netdev_err(ndp->ndev.dev, 739 734 "Failed to add new VLAN tag, error %d\n", index); 735 + if (index == -ENOSPC) 736 + netdev_err(ndp->ndev.dev, 737 + "Channel %u already has all VLAN filters set\n", 738 + nc->id); 740 739 return -1; 741 740 } 742 741 ··· 1007 998 struct ncsi_package *np; 1008 999 struct ncsi_channel *nc; 1009 1000 unsigned int cap; 1001 + bool has_channel = false; 1010 1002 1011 1003 /* The hardware arbitration is disabled if any one channel 1012 1004 * doesn't support explicitly. 1013 1005 */ 1014 1006 NCSI_FOR_EACH_PACKAGE(ndp, np) { 1015 1007 NCSI_FOR_EACH_CHANNEL(np, nc) { 1008 + has_channel = true; 1009 + 1016 1010 cap = nc->caps[NCSI_CAP_GENERIC].cap; 1017 1011 if (!(cap & NCSI_CAP_GENERIC_HWA) || 1018 1012 (cap & NCSI_CAP_GENERIC_HWA_MASK) != ··· 1026 1014 } 1027 1015 } 1028 1016 1029 - ndp->flags |= NCSI_DEV_HWA; 1030 - return true; 1017 + if (has_channel) { 1018 + ndp->flags |= NCSI_DEV_HWA; 1019 + return true; 1020 + } 1021 + 1022 + ndp->flags &= ~NCSI_DEV_HWA; 1023 + return false; 1031 1024 } 1032 1025 1033 1026 static int ncsi_enable_hwa(struct ncsi_dev_priv *ndp) ··· 1420 1403 1421 1404 int ncsi_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) 1422 1405 { 1423 - struct ncsi_channel_filter *ncf; 1424 1406 struct ncsi_dev_priv *ndp; 1425 1407 unsigned int n_vids = 0; 1426 1408 struct vlan_vid *vlan; ··· 1436 1420 } 1437 1421 1438 1422 ndp = TO_NCSI_DEV_PRIV(nd); 1439 - ncf = ndp->hot_channel->filters[NCSI_FILTER_VLAN]; 1440 1423 1441 1424 /* Add the VLAN id to our internal list */ 1442 1425 list_for_each_entry_rcu(vlan, &ndp->vlan_vids, list) { ··· 1446 1431 return 0; 1447 1432 } 1448 1433 } 1449 - 1450 - if (n_vids >= ncf->total) { 1451 - netdev_info(dev, 1452 - "NCSI Channel supports up to %u VLAN tags but %u are already set\n", 1453 - ncf->total, n_vids); 1454 - return -EINVAL; 1434 + if (n_vids >= NCSI_MAX_VLAN_VIDS) { 1435 + netdev_warn(dev, 1436 + "tried to add vlan id %u but NCSI max already registered (%u)\n", 1437 + vid, NCSI_MAX_VLAN_VIDS); 1438 + return -ENOSPC; 1455 1439 } 1456 1440 1457 1441 vlan = kzalloc(sizeof(*vlan), GFP_KERNEL);
+1 -1
net/ncsi/ncsi-rsp.c
··· 959 959 { NCSI_PKT_RSP_EGMF, 4, ncsi_rsp_handler_egmf }, 960 960 { NCSI_PKT_RSP_DGMF, 4, ncsi_rsp_handler_dgmf }, 961 961 { NCSI_PKT_RSP_SNFC, 4, ncsi_rsp_handler_snfc }, 962 - { NCSI_PKT_RSP_GVI, 36, ncsi_rsp_handler_gvi }, 962 + { NCSI_PKT_RSP_GVI, 40, ncsi_rsp_handler_gvi }, 963 963 { NCSI_PKT_RSP_GC, 32, ncsi_rsp_handler_gc }, 964 964 { NCSI_PKT_RSP_GP, -1, ncsi_rsp_handler_gp }, 965 965 { NCSI_PKT_RSP_GCPS, 172, ncsi_rsp_handler_gcps },
+4 -4
net/netlink/af_netlink.c
··· 2307 2307 size_t tlvlen = 0; 2308 2308 struct netlink_sock *nlk = nlk_sk(NETLINK_CB(in_skb).sk); 2309 2309 unsigned int flags = 0; 2310 + bool nlk_has_extack = nlk->flags & NETLINK_F_EXT_ACK; 2310 2311 2311 2312 /* Error messages get the original request appened, unless the user 2312 2313 * requests to cap the error message, and get extra error data if ··· 2318 2317 payload += nlmsg_len(nlh); 2319 2318 else 2320 2319 flags |= NLM_F_CAPPED; 2321 - if (nlk->flags & NETLINK_F_EXT_ACK && extack) { 2320 + if (nlk_has_extack && extack) { 2322 2321 if (extack->_msg) 2323 2322 tlvlen += nla_total_size(strlen(extack->_msg) + 1); 2324 2323 if (extack->bad_attr) ··· 2327 2326 } else { 2328 2327 flags |= NLM_F_CAPPED; 2329 2328 2330 - if (nlk->flags & NETLINK_F_EXT_ACK && 2331 - extack && extack->cookie_len) 2329 + if (nlk_has_extack && extack && extack->cookie_len) 2332 2330 tlvlen += nla_total_size(extack->cookie_len); 2333 2331 } 2334 2332 ··· 2355 2355 errmsg->error = err; 2356 2356 memcpy(&errmsg->msg, nlh, payload > sizeof(*errmsg) ? nlh->nlmsg_len : sizeof(*nlh)); 2357 2357 2358 - if (nlk->flags & NETLINK_F_EXT_ACK && extack) { 2358 + if (nlk_has_extack && extack) { 2359 2359 if (err) { 2360 2360 if (extack->_msg) 2361 2361 WARN_ON(nla_put_string(skb, NLMSGERR_ATTR_MSG,
+16 -8
net/packet/af_packet.c
··· 1769 1769 1770 1770 out: 1771 1771 if (err && rollover) { 1772 - kfree(rollover); 1772 + kfree_rcu(rollover, rcu); 1773 1773 po->rollover = NULL; 1774 1774 } 1775 1775 mutex_unlock(&fanout_mutex); ··· 1796 1796 else 1797 1797 f = NULL; 1798 1798 1799 - if (po->rollover) 1799 + if (po->rollover) { 1800 1800 kfree_rcu(po->rollover, rcu); 1801 + po->rollover = NULL; 1802 + } 1801 1803 } 1802 1804 mutex_unlock(&fanout_mutex); 1803 1805 ··· 3853 3851 void *data = &val; 3854 3852 union tpacket_stats_u st; 3855 3853 struct tpacket_rollover_stats rstats; 3854 + struct packet_rollover *rollover; 3856 3855 3857 3856 if (level != SOL_PACKET) 3858 3857 return -ENOPROTOOPT; ··· 3932 3929 0); 3933 3930 break; 3934 3931 case PACKET_ROLLOVER_STATS: 3935 - if (!po->rollover) 3932 + rcu_read_lock(); 3933 + rollover = rcu_dereference(po->rollover); 3934 + if (rollover) { 3935 + rstats.tp_all = atomic_long_read(&rollover->num); 3936 + rstats.tp_huge = atomic_long_read(&rollover->num_huge); 3937 + rstats.tp_failed = atomic_long_read(&rollover->num_failed); 3938 + data = &rstats; 3939 + lv = sizeof(rstats); 3940 + } 3941 + rcu_read_unlock(); 3942 + if (!rollover) 3936 3943 return -EINVAL; 3937 - rstats.tp_all = atomic_long_read(&po->rollover->num); 3938 - rstats.tp_huge = atomic_long_read(&po->rollover->num_huge); 3939 - rstats.tp_failed = atomic_long_read(&po->rollover->num_failed); 3940 - data = &rstats; 3941 - lv = sizeof(rstats); 3942 3944 break; 3943 3945 case PACKET_TX_HAS_OFF: 3944 3946 val = po->tp_tx_has_off;
+3 -2
net/rxrpc/af_rxrpc.c
··· 308 308 call = rxrpc_new_client_call(rx, &cp, srx, user_call_ID, tx_total_len, 309 309 gfp); 310 310 /* The socket has been unlocked. */ 311 - if (!IS_ERR(call)) 311 + if (!IS_ERR(call)) { 312 312 call->notify_rx = notify_rx; 313 + mutex_unlock(&call->user_mutex); 314 + } 313 315 314 - mutex_unlock(&call->user_mutex); 315 316 _leave(" = %p", call); 316 317 return call; 317 318 }
+2
net/sched/cls_flower.c
··· 234 234 tc_cls_common_offload_init(&cls_flower.common, tp); 235 235 cls_flower.command = TC_CLSFLOWER_DESTROY; 236 236 cls_flower.cookie = (unsigned long) f; 237 + cls_flower.egress_dev = f->hw_dev != tp->q->dev_queue->dev; 237 238 238 239 dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER, &cls_flower); 239 240 } ··· 290 289 cls_flower.command = TC_CLSFLOWER_STATS; 291 290 cls_flower.cookie = (unsigned long) f; 292 291 cls_flower.exts = &f->exts; 292 + cls_flower.egress_dev = f->hw_dev != tp->q->dev_queue->dev; 293 293 294 294 dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_CLSFLOWER, 295 295 &cls_flower);
+1 -1
net/sctp/input.c
··· 421 421 { 422 422 struct dst_entry *dst; 423 423 424 - if (!t) 424 + if (sock_owned_by_user(sk) || !t) 425 425 return; 426 426 dst = sctp_transport_dst_check(t); 427 427 if (dst)
+4
net/sctp/socket.c
··· 4906 4906 struct socket *sock; 4907 4907 int err = 0; 4908 4908 4909 + /* Do not peel off from one netns to another one. */ 4910 + if (!net_eq(current->nsproxy->net_ns, sock_net(sk))) 4911 + return -EINVAL; 4912 + 4909 4913 if (!asoc) 4910 4914 return -EINVAL; 4911 4915
+18 -4
net/vmw_vsock/hyperv_transport.c
··· 310 310 struct sock *sk = get_per_channel_state(chan); 311 311 struct vsock_sock *vsk = vsock_sk(sk); 312 312 313 + lock_sock(sk); 314 + 313 315 sk->sk_state = SS_UNCONNECTED; 314 316 sock_set_flag(sk, SOCK_DONE); 315 317 vsk->peer_shutdown |= SEND_SHUTDOWN | RCV_SHUTDOWN; 316 318 317 319 sk->sk_state_change(sk); 320 + 321 + release_sock(sk); 318 322 } 319 323 320 324 static void hvs_open_connection(struct vmbus_channel *chan) ··· 347 343 sk = vsock_find_bound_socket(&addr); 348 344 if (!sk) 349 345 return; 346 + 347 + lock_sock(sk); 350 348 351 349 if ((conn_from_host && sk->sk_state != VSOCK_SS_LISTEN) || 352 350 (!conn_from_host && sk->sk_state != SS_CONNECTING)) ··· 401 395 402 396 vsock_insert_connected(vnew); 403 397 404 - lock_sock(sk); 405 398 vsock_enqueue_accept(sk, new); 406 - release_sock(sk); 407 399 } else { 408 400 sk->sk_state = SS_CONNECTED; 409 401 sk->sk_socket->state = SS_CONNECTED; ··· 414 410 out: 415 411 /* Release refcnt obtained when we called vsock_find_bound_socket() */ 416 412 sock_put(sk); 413 + 414 + release_sock(sk); 417 415 } 418 416 419 417 static u32 hvs_get_local_cid(void) ··· 482 476 483 477 static void hvs_release(struct vsock_sock *vsk) 484 478 { 479 + struct sock *sk = sk_vsock(vsk); 485 480 struct hvsock *hvs = vsk->trans; 486 - struct vmbus_channel *chan = hvs->chan; 481 + struct vmbus_channel *chan; 487 482 483 + lock_sock(sk); 484 + 485 + sk->sk_state = SS_DISCONNECTING; 486 + vsock_remove_sock(vsk); 487 + 488 + release_sock(sk); 489 + 490 + chan = hvs->chan; 488 491 if (chan) 489 492 hvs_shutdown(vsk, RCV_SHUTDOWN | SEND_SHUTDOWN); 490 493 491 - vsock_remove_sock(vsk); 492 494 } 493 495 494 496 static void hvs_destruct(struct vsock_sock *vsk)
+1 -1
samples/sockmap/sockmap_kern.c
··· 62 62 ret = 1; 63 63 64 64 bpf_printk("sockmap: %d -> %d @ %d\n", lport, bpf_ntohl(rport), ret); 65 - return bpf_sk_redirect_map(&sock_map, ret, 0); 65 + return bpf_sk_redirect_map(skb, &sock_map, ret, 0); 66 66 } 67 67 68 68 SEC("sockops")
+2 -1
tools/include/uapi/linux/bpf.h
··· 569 569 * @flags: reserved for future use 570 570 * Return: 0 on success or negative error code 571 571 * 572 - * int bpf_sk_redirect_map(map, key, flags) 572 + * int bpf_sk_redirect_map(skb, map, key, flags) 573 573 * Redirect skb to a sock in map using key as a lookup key for the 574 574 * sock in map. 575 + * @skb: pointer to skb 575 576 * @map: pointer to sockmap 576 577 * @key: key to lookup sock in map 577 578 * @flags: reserved for future use
+1 -1
tools/testing/selftests/bpf/bpf_helpers.h
··· 65 65 static int (*bpf_setsockopt)(void *ctx, int level, int optname, void *optval, 66 66 int optlen) = 67 67 (void *) BPF_FUNC_setsockopt; 68 - static int (*bpf_sk_redirect_map)(void *map, int key, int flags) = 68 + static int (*bpf_sk_redirect_map)(void *ctx, void *map, int key, int flags) = 69 69 (void *) BPF_FUNC_sk_redirect_map; 70 70 static int (*bpf_sock_map_update)(void *map, void *key, void *value, 71 71 unsigned long long flags) =
+2 -2
tools/testing/selftests/bpf/sockmap_verdict_prog.c
··· 61 61 bpf_printk("verdict: data[0] = redir(%u:%u)\n", map, sk); 62 62 63 63 if (!map) 64 - return bpf_sk_redirect_map(&sock_map_rx, sk, 0); 65 - return bpf_sk_redirect_map(&sock_map_tx, sk, 0); 64 + return bpf_sk_redirect_map(skb, &sock_map_rx, sk, 0); 65 + return bpf_sk_redirect_map(skb, &sock_map_tx, sk, 0); 66 66 } 67 67 68 68 char _license[] SEC("license") = "GPL";
+11 -1
tools/testing/selftests/bpf/test_maps.c
··· 466 466 int one = 1, map_fd_rx, map_fd_tx, map_fd_break, s, sc, rc; 467 467 struct bpf_map *bpf_map_rx, *bpf_map_tx, *bpf_map_break; 468 468 int ports[] = {50200, 50201, 50202, 50204}; 469 - int err, i, fd, sfd[6] = {0xdeadbeef}; 469 + int err, i, fd, udp, sfd[6] = {0xdeadbeef}; 470 470 u8 buf[20] = {0x0, 0x5, 0x3, 0x2, 0x1, 0x0}; 471 471 int parse_prog, verdict_prog; 472 472 struct sockaddr_in addr; ··· 545 545 6, 0); 546 546 if (fd < 0) { 547 547 printf("Failed to create sockmap %i\n", fd); 548 + goto out_sockmap; 549 + } 550 + 551 + /* Test update with unsupported UDP socket */ 552 + udp = socket(AF_INET, SOCK_DGRAM, 0); 553 + i = 0; 554 + err = bpf_map_update_elem(fd, &i, &udp, BPF_ANY); 555 + if (!err) { 556 + printf("Failed socket SOCK_DGRAM allowed '%i:%i'\n", 557 + i, udp); 548 558 goto out_sockmap; 549 559 } 550 560
+508 -2
tools/testing/selftests/bpf/test_verifier.c
··· 1130 1130 .errstr = "invalid bpf_context access", 1131 1131 }, 1132 1132 { 1133 - "check skb->mark is writeable by SK_SKB", 1133 + "invalid access of skb->mark for SK_SKB", 1134 + .insns = { 1135 + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 1136 + offsetof(struct __sk_buff, mark)), 1137 + BPF_EXIT_INSN(), 1138 + }, 1139 + .result = REJECT, 1140 + .prog_type = BPF_PROG_TYPE_SK_SKB, 1141 + .errstr = "invalid bpf_context access", 1142 + }, 1143 + { 1144 + "check skb->mark is not writeable by SK_SKB", 1134 1145 .insns = { 1135 1146 BPF_MOV64_IMM(BPF_REG_0, 0), 1136 1147 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 1137 1148 offsetof(struct __sk_buff, mark)), 1138 1149 BPF_EXIT_INSN(), 1139 1150 }, 1140 - .result = ACCEPT, 1151 + .result = REJECT, 1141 1152 .prog_type = BPF_PROG_TYPE_SK_SKB, 1153 + .errstr = "invalid bpf_context access", 1142 1154 }, 1143 1155 { 1144 1156 "check skb->tc_index is writeable by SK_SKB", ··· 6656 6644 }, 6657 6645 .errstr = "BPF_END uses reserved fields", 6658 6646 .result = REJECT, 6647 + }, 6648 + { 6649 + "arithmetic ops make PTR_TO_CTX unusable", 6650 + .insns = { 6651 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 6652 + offsetof(struct __sk_buff, data) - 6653 + offsetof(struct __sk_buff, mark)), 6654 + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 6655 + offsetof(struct __sk_buff, mark)), 6656 + BPF_EXIT_INSN(), 6657 + }, 6658 + .errstr = "dereference of modified ctx ptr R1 off=68+8, ctx+const is allowed, ctx+const+const is not", 6659 + .result = REJECT, 6660 + .prog_type = BPF_PROG_TYPE_SCHED_CLS, 6661 + }, 6662 + { 6663 + "XDP pkt read, pkt_end mangling, bad access 1", 6664 + .insns = { 6665 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6666 + offsetof(struct xdp_md, data)), 6667 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6668 + offsetof(struct xdp_md, data_end)), 6669 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6670 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6671 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8), 6672 + BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), 6673 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6674 + BPF_MOV64_IMM(BPF_REG_0, 0), 6675 + BPF_EXIT_INSN(), 6676 + }, 6677 + .errstr = "R1 offset is outside of the packet", 6678 + .result = REJECT, 6679 + .prog_type = BPF_PROG_TYPE_XDP, 6680 + }, 6681 + { 6682 + "XDP pkt read, pkt_end mangling, bad access 2", 6683 + .insns = { 6684 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6685 + offsetof(struct xdp_md, data)), 6686 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6687 + offsetof(struct xdp_md, data_end)), 6688 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6689 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6690 + BPF_ALU64_IMM(BPF_SUB, BPF_REG_3, 8), 6691 + BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), 6692 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6693 + BPF_MOV64_IMM(BPF_REG_0, 0), 6694 + BPF_EXIT_INSN(), 6695 + }, 6696 + .errstr = "R1 offset is outside of the packet", 6697 + .result = REJECT, 6698 + .prog_type = BPF_PROG_TYPE_XDP, 6699 + }, 6700 + { 6701 + "XDP pkt read, pkt_data' > pkt_end, good access", 6702 + .insns = { 6703 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6704 + offsetof(struct xdp_md, data)), 6705 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6706 + offsetof(struct xdp_md, data_end)), 6707 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6708 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6709 + BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), 6710 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6711 + BPF_MOV64_IMM(BPF_REG_0, 0), 6712 + BPF_EXIT_INSN(), 6713 + }, 6714 + .result = ACCEPT, 6715 + .prog_type = BPF_PROG_TYPE_XDP, 6716 + }, 6717 + { 6718 + "XDP pkt read, pkt_data' > pkt_end, bad access 1", 6719 + .insns = { 6720 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6721 + offsetof(struct xdp_md, data)), 6722 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6723 + offsetof(struct xdp_md, data_end)), 6724 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6725 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6726 + BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 1), 6727 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4), 6728 + BPF_MOV64_IMM(BPF_REG_0, 0), 6729 + BPF_EXIT_INSN(), 6730 + }, 6731 + .errstr = "R1 offset is outside of the packet", 6732 + .result = REJECT, 6733 + .prog_type = BPF_PROG_TYPE_XDP, 6734 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 6735 + }, 6736 + { 6737 + "XDP pkt read, pkt_data' > pkt_end, bad access 2", 6738 + .insns = { 6739 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6740 + offsetof(struct xdp_md, data)), 6741 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6742 + offsetof(struct xdp_md, data_end)), 6743 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6744 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6745 + BPF_JMP_REG(BPF_JGT, BPF_REG_1, BPF_REG_3, 0), 6746 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6747 + BPF_MOV64_IMM(BPF_REG_0, 0), 6748 + BPF_EXIT_INSN(), 6749 + }, 6750 + .errstr = "R1 offset is outside of the packet", 6751 + .result = REJECT, 6752 + .prog_type = BPF_PROG_TYPE_XDP, 6753 + }, 6754 + { 6755 + "XDP pkt read, pkt_end > pkt_data', good access", 6756 + .insns = { 6757 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6758 + offsetof(struct xdp_md, data)), 6759 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6760 + offsetof(struct xdp_md, data_end)), 6761 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6762 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6763 + BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), 6764 + BPF_JMP_IMM(BPF_JA, 0, 0, 1), 6765 + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), 6766 + BPF_MOV64_IMM(BPF_REG_0, 0), 6767 + BPF_EXIT_INSN(), 6768 + }, 6769 + .result = ACCEPT, 6770 + .prog_type = BPF_PROG_TYPE_XDP, 6771 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 6772 + }, 6773 + { 6774 + "XDP pkt read, pkt_end > pkt_data', bad access 1", 6775 + .insns = { 6776 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6777 + offsetof(struct xdp_md, data)), 6778 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6779 + offsetof(struct xdp_md, data_end)), 6780 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6781 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6782 + BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), 6783 + BPF_JMP_IMM(BPF_JA, 0, 0, 1), 6784 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6785 + BPF_MOV64_IMM(BPF_REG_0, 0), 6786 + BPF_EXIT_INSN(), 6787 + }, 6788 + .errstr = "R1 offset is outside of the packet", 6789 + .result = REJECT, 6790 + .prog_type = BPF_PROG_TYPE_XDP, 6791 + }, 6792 + { 6793 + "XDP pkt read, pkt_end > pkt_data', bad access 2", 6794 + .insns = { 6795 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6796 + offsetof(struct xdp_md, data)), 6797 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6798 + offsetof(struct xdp_md, data_end)), 6799 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6800 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6801 + BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_1, 1), 6802 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6803 + BPF_MOV64_IMM(BPF_REG_0, 0), 6804 + BPF_EXIT_INSN(), 6805 + }, 6806 + .errstr = "R1 offset is outside of the packet", 6807 + .result = REJECT, 6808 + .prog_type = BPF_PROG_TYPE_XDP, 6809 + }, 6810 + { 6811 + "XDP pkt read, pkt_data' < pkt_end, good access", 6812 + .insns = { 6813 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6814 + offsetof(struct xdp_md, data)), 6815 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6816 + offsetof(struct xdp_md, data_end)), 6817 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6818 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6819 + BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), 6820 + BPF_JMP_IMM(BPF_JA, 0, 0, 1), 6821 + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), 6822 + BPF_MOV64_IMM(BPF_REG_0, 0), 6823 + BPF_EXIT_INSN(), 6824 + }, 6825 + .result = ACCEPT, 6826 + .prog_type = BPF_PROG_TYPE_XDP, 6827 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 6828 + }, 6829 + { 6830 + "XDP pkt read, pkt_data' < pkt_end, bad access 1", 6831 + .insns = { 6832 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6833 + offsetof(struct xdp_md, data)), 6834 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6835 + offsetof(struct xdp_md, data_end)), 6836 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6837 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6838 + BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), 6839 + BPF_JMP_IMM(BPF_JA, 0, 0, 1), 6840 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6841 + BPF_MOV64_IMM(BPF_REG_0, 0), 6842 + BPF_EXIT_INSN(), 6843 + }, 6844 + .errstr = "R1 offset is outside of the packet", 6845 + .result = REJECT, 6846 + .prog_type = BPF_PROG_TYPE_XDP, 6847 + }, 6848 + { 6849 + "XDP pkt read, pkt_data' < pkt_end, bad access 2", 6850 + .insns = { 6851 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6852 + offsetof(struct xdp_md, data)), 6853 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6854 + offsetof(struct xdp_md, data_end)), 6855 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6856 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6857 + BPF_JMP_REG(BPF_JLT, BPF_REG_1, BPF_REG_3, 1), 6858 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6859 + BPF_MOV64_IMM(BPF_REG_0, 0), 6860 + BPF_EXIT_INSN(), 6861 + }, 6862 + .errstr = "R1 offset is outside of the packet", 6863 + .result = REJECT, 6864 + .prog_type = BPF_PROG_TYPE_XDP, 6865 + }, 6866 + { 6867 + "XDP pkt read, pkt_end < pkt_data', good access", 6868 + .insns = { 6869 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6870 + offsetof(struct xdp_md, data)), 6871 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6872 + offsetof(struct xdp_md, data_end)), 6873 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6874 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6875 + BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1), 6876 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6877 + BPF_MOV64_IMM(BPF_REG_0, 0), 6878 + BPF_EXIT_INSN(), 6879 + }, 6880 + .result = ACCEPT, 6881 + .prog_type = BPF_PROG_TYPE_XDP, 6882 + }, 6883 + { 6884 + "XDP pkt read, pkt_end < pkt_data', bad access 1", 6885 + .insns = { 6886 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6887 + offsetof(struct xdp_md, data)), 6888 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6889 + offsetof(struct xdp_md, data_end)), 6890 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6891 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6892 + BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 1), 6893 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4), 6894 + BPF_MOV64_IMM(BPF_REG_0, 0), 6895 + BPF_EXIT_INSN(), 6896 + }, 6897 + .errstr = "R1 offset is outside of the packet", 6898 + .result = REJECT, 6899 + .prog_type = BPF_PROG_TYPE_XDP, 6900 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 6901 + }, 6902 + { 6903 + "XDP pkt read, pkt_end < pkt_data', bad access 2", 6904 + .insns = { 6905 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6906 + offsetof(struct xdp_md, data)), 6907 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6908 + offsetof(struct xdp_md, data_end)), 6909 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6910 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6911 + BPF_JMP_REG(BPF_JLT, BPF_REG_3, BPF_REG_1, 0), 6912 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6913 + BPF_MOV64_IMM(BPF_REG_0, 0), 6914 + BPF_EXIT_INSN(), 6915 + }, 6916 + .errstr = "R1 offset is outside of the packet", 6917 + .result = REJECT, 6918 + .prog_type = BPF_PROG_TYPE_XDP, 6919 + }, 6920 + { 6921 + "XDP pkt read, pkt_data' >= pkt_end, good access", 6922 + .insns = { 6923 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6924 + offsetof(struct xdp_md, data)), 6925 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6926 + offsetof(struct xdp_md, data_end)), 6927 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6928 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6929 + BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), 6930 + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), 6931 + BPF_MOV64_IMM(BPF_REG_0, 0), 6932 + BPF_EXIT_INSN(), 6933 + }, 6934 + .result = ACCEPT, 6935 + .prog_type = BPF_PROG_TYPE_XDP, 6936 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 6937 + }, 6938 + { 6939 + "XDP pkt read, pkt_data' >= pkt_end, bad access 1", 6940 + .insns = { 6941 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6942 + offsetof(struct xdp_md, data)), 6943 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6944 + offsetof(struct xdp_md, data_end)), 6945 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6946 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6947 + BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 1), 6948 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6949 + BPF_MOV64_IMM(BPF_REG_0, 0), 6950 + BPF_EXIT_INSN(), 6951 + }, 6952 + .errstr = "R1 offset is outside of the packet", 6953 + .result = REJECT, 6954 + .prog_type = BPF_PROG_TYPE_XDP, 6955 + }, 6956 + { 6957 + "XDP pkt read, pkt_data' >= pkt_end, bad access 2", 6958 + .insns = { 6959 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6960 + offsetof(struct xdp_md, data)), 6961 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6962 + offsetof(struct xdp_md, data_end)), 6963 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6964 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6965 + BPF_JMP_REG(BPF_JGE, BPF_REG_1, BPF_REG_3, 0), 6966 + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), 6967 + BPF_MOV64_IMM(BPF_REG_0, 0), 6968 + BPF_EXIT_INSN(), 6969 + }, 6970 + .errstr = "R1 offset is outside of the packet", 6971 + .result = REJECT, 6972 + .prog_type = BPF_PROG_TYPE_XDP, 6973 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 6974 + }, 6975 + { 6976 + "XDP pkt read, pkt_end >= pkt_data', good access", 6977 + .insns = { 6978 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6979 + offsetof(struct xdp_md, data)), 6980 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6981 + offsetof(struct xdp_md, data_end)), 6982 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 6983 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 6984 + BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), 6985 + BPF_JMP_IMM(BPF_JA, 0, 0, 1), 6986 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 6987 + BPF_MOV64_IMM(BPF_REG_0, 0), 6988 + BPF_EXIT_INSN(), 6989 + }, 6990 + .result = ACCEPT, 6991 + .prog_type = BPF_PROG_TYPE_XDP, 6992 + }, 6993 + { 6994 + "XDP pkt read, pkt_end >= pkt_data', bad access 1", 6995 + .insns = { 6996 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 6997 + offsetof(struct xdp_md, data)), 6998 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 6999 + offsetof(struct xdp_md, data_end)), 7000 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 7001 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7002 + BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), 7003 + BPF_JMP_IMM(BPF_JA, 0, 0, 1), 7004 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4), 7005 + BPF_MOV64_IMM(BPF_REG_0, 0), 7006 + BPF_EXIT_INSN(), 7007 + }, 7008 + .errstr = "R1 offset is outside of the packet", 7009 + .result = REJECT, 7010 + .prog_type = BPF_PROG_TYPE_XDP, 7011 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 7012 + }, 7013 + { 7014 + "XDP pkt read, pkt_end >= pkt_data', bad access 2", 7015 + .insns = { 7016 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7017 + offsetof(struct xdp_md, data)), 7018 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 7019 + offsetof(struct xdp_md, data_end)), 7020 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 7021 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7022 + BPF_JMP_REG(BPF_JGE, BPF_REG_3, BPF_REG_1, 1), 7023 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 7024 + BPF_MOV64_IMM(BPF_REG_0, 0), 7025 + BPF_EXIT_INSN(), 7026 + }, 7027 + .errstr = "R1 offset is outside of the packet", 7028 + .result = REJECT, 7029 + .prog_type = BPF_PROG_TYPE_XDP, 7030 + }, 7031 + { 7032 + "XDP pkt read, pkt_data' <= pkt_end, good access", 7033 + .insns = { 7034 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7035 + offsetof(struct xdp_md, data)), 7036 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 7037 + offsetof(struct xdp_md, data_end)), 7038 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 7039 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7040 + BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), 7041 + BPF_JMP_IMM(BPF_JA, 0, 0, 1), 7042 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 7043 + BPF_MOV64_IMM(BPF_REG_0, 0), 7044 + BPF_EXIT_INSN(), 7045 + }, 7046 + .result = ACCEPT, 7047 + .prog_type = BPF_PROG_TYPE_XDP, 7048 + }, 7049 + { 7050 + "XDP pkt read, pkt_data' <= pkt_end, bad access 1", 7051 + .insns = { 7052 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7053 + offsetof(struct xdp_md, data)), 7054 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 7055 + offsetof(struct xdp_md, data_end)), 7056 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 7057 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7058 + BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), 7059 + BPF_JMP_IMM(BPF_JA, 0, 0, 1), 7060 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -4), 7061 + BPF_MOV64_IMM(BPF_REG_0, 0), 7062 + BPF_EXIT_INSN(), 7063 + }, 7064 + .errstr = "R1 offset is outside of the packet", 7065 + .result = REJECT, 7066 + .prog_type = BPF_PROG_TYPE_XDP, 7067 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 7068 + }, 7069 + { 7070 + "XDP pkt read, pkt_data' <= pkt_end, bad access 2", 7071 + .insns = { 7072 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7073 + offsetof(struct xdp_md, data)), 7074 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 7075 + offsetof(struct xdp_md, data_end)), 7076 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 7077 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7078 + BPF_JMP_REG(BPF_JLE, BPF_REG_1, BPF_REG_3, 1), 7079 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 7080 + BPF_MOV64_IMM(BPF_REG_0, 0), 7081 + BPF_EXIT_INSN(), 7082 + }, 7083 + .errstr = "R1 offset is outside of the packet", 7084 + .result = REJECT, 7085 + .prog_type = BPF_PROG_TYPE_XDP, 7086 + }, 7087 + { 7088 + "XDP pkt read, pkt_end <= pkt_data', good access", 7089 + .insns = { 7090 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7091 + offsetof(struct xdp_md, data)), 7092 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 7093 + offsetof(struct xdp_md, data_end)), 7094 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 7095 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7096 + BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1), 7097 + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), 7098 + BPF_MOV64_IMM(BPF_REG_0, 0), 7099 + BPF_EXIT_INSN(), 7100 + }, 7101 + .result = ACCEPT, 7102 + .prog_type = BPF_PROG_TYPE_XDP, 7103 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 7104 + }, 7105 + { 7106 + "XDP pkt read, pkt_end <= pkt_data', bad access 1", 7107 + .insns = { 7108 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7109 + offsetof(struct xdp_md, data)), 7110 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 7111 + offsetof(struct xdp_md, data_end)), 7112 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 7113 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7114 + BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 1), 7115 + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8), 7116 + BPF_MOV64_IMM(BPF_REG_0, 0), 7117 + BPF_EXIT_INSN(), 7118 + }, 7119 + .errstr = "R1 offset is outside of the packet", 7120 + .result = REJECT, 7121 + .prog_type = BPF_PROG_TYPE_XDP, 7122 + }, 7123 + { 7124 + "XDP pkt read, pkt_end <= pkt_data', bad access 2", 7125 + .insns = { 7126 + BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 7127 + offsetof(struct xdp_md, data)), 7128 + BPF_LDX_MEM(BPF_W, BPF_REG_3, BPF_REG_1, 7129 + offsetof(struct xdp_md, data_end)), 7130 + BPF_MOV64_REG(BPF_REG_1, BPF_REG_2), 7131 + BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 8), 7132 + BPF_JMP_REG(BPF_JLE, BPF_REG_3, BPF_REG_1, 0), 7133 + BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, -5), 7134 + BPF_MOV64_IMM(BPF_REG_0, 0), 7135 + BPF_EXIT_INSN(), 7136 + }, 7137 + .errstr = "R1 offset is outside of the packet", 7138 + .result = REJECT, 7139 + .prog_type = BPF_PROG_TYPE_XDP, 7140 + .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, 6659 7141 }, 6660 7142 }; 6661 7143