Pull networking fixes from Jakub Kicinski: "Including fixes from xfrm, bpf, netfilter, and wireless. Current release - regressions: - xfrm: fix XFRM_MSG_MAPPING ABI breakage caused by inserting a new value in the middle of an enum - unix: fix an issue in unix_shutdown causing the other end read/write failures - phy: mdio: fix memory leak Current release - new code bugs: - mlx5e: improve MQPRIO resiliency against bad configs Previous releases - regressions: - bpf: fix integer overflow leading to OOB access in map element pre-allocation - stmmac: dwmac-rk: fix ethernet on rk3399 based devices - netfilter: conntrack: fix boot failure with nf_conntrack.enable_hooks=1 - brcmfmac: revert using ISO3166 country code and 0 rev as fallback - i40e: fix freeing of uninitialized misc IRQ vector - iavf: fix double unlock of crit_lock Previous releases - always broken: - bpf, arm: fix register clobbering in div/mod implementation - netfilter: nf_tables: correct issues in netlink rule change event notifications - dsa: tag_dsa: fix mask for trunked packets - usb: r8152: don't resubmit rx immediately to avoid soft lockup on device unplug - i40e: fix endless loop under rtnl if FW fails to correctly respond to capability query - mlx5e: fix rx checksum offload coexistence with ipsec offload - mlx5: force round second at 1PPS out start time and allow it only in supported clock modes - phy: pcs: xpcs: fix incorrect CL37 AN sequence, EEE disable sequence Misc: - xfrm: slightly rejig the new policy uAPI to make it less cryptic" * tag 'net-5.15-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (66 commits) net: prefer socket bound to interface when not in VRF iavf: fix double unlock of crit_lock i40e: Fix freeing of uninitialized misc IRQ vector i40e: fix endless loop under rtnl dt-bindings: net: dsa: marvell: fix compatible in example ionic: move filter sync_needed bit set gve: report 64bit tx_bytes counter from gve_handle_report_stats() gve: fix gve_get_stats() rtnetlink: fix if_nlmsg_stats_size() under estimation gve: Properly handle errors in gve_assign_qpl gve: Avoid freeing NULL pointer gve: Correct available tx qpl check unix: Fix an issue in unix_shutdown causing the other end read/write failures net: stmmac: trigger PCS EEE to turn off on link down net: pcs: xpcs: fix incorrect steps on disable EEE netlink: annotate data races around nlk->bound net: pcs: xpcs: fix incorrect CL37 AN sequence net: sfp: Fix typo in state machine debug string net/sched: sch_taprio: properly cancel timer from taprio_destroy() net: bridge: fix under estimation in br_get_linkxstats_size() ...
Unified · Split
| @@ -971,6 +971,7 @@ D: PowerPC · 970 unmodified lines | ||
| 971 | 971 | N: Daniel Drake |
| 972 | 972 | E: dsd@gentoo.org |
| 973 | 973 | D: USBAT02 CompactFlash support in usb-storage |
| 974 | +D: ZD1211RW wireless driver | |
| 974 | 975 | S: UK |
| 975 | 976 | |
| 976 | 977 | N: Oleg Drokin |
| @@ -83,7 +83,7 @@ Example: · 82 unmodified lines | ||
| 83 | 83 | #interrupt-cells = <2>; |
| 84 | 84 | |
| 85 | 85 | switch0: switch@0 { |
| 86 | − compatible = "marvell,mv88e6390"; | |
| 86 | + compatible = "marvell,mv88e6190"; | |
| 87 | 87 | reg = <0>; |
| 88 | 88 | reset-gpios = <&gpio5 1 GPIO_ACTIVE_LOW>; |
| 89 | 89 | |
| @@ -8609,9 +8609,8 @@ F: Documentation/devicetree/bindings/iio/humidity/st,hts221.yaml · 8608 unmodified lines | ||
| 8609 | 8609 | F: drivers/iio/humidity/hts221* |
| 8610 | 8610 | |
| 8611 | 8611 | HUAWEI ETHERNET DRIVER |
| 8612 | −M: Bin Luo <luobin9@huawei.com> | |
| 8613 | 8612 | L: netdev@vger.kernel.org |
| 8614 | −S: Supported | |
| 8613 | +S: Orphan | |
| 8615 | 8614 | F: Documentation/networking/device_drivers/ethernet/huawei/hinic.rst |
| 8616 | 8615 | F: drivers/net/ethernet/huawei/hinic/ |
| 8617 | 8616 | |
| @@ -17794,7 +17793,6 @@ F: drivers/staging/nvec/ · 9176 unmodified lines | ||
| 17794 | 17793 | |
| 17795 | 17794 | STAGING - OLPC SECONDARY DISPLAY CONTROLLER (DCON) |
| 17796 | 17795 | M: Jens Frederich <jfrederich@gmail.com> |
| 17797 | −M: Daniel Drake <dsd@laptop.org> | |
| 17798 | 17796 | M: Jon Nettleton <jon.nettleton@gmail.com> |
| 17799 | 17797 | S: Maintained |
| 17800 | 17798 | W: http://wiki.laptop.org/go/DCON |
| @@ -20700,7 +20698,6 @@ S: Maintained · 2899 unmodified lines | ||
| 20700 | 20698 | F: mm/zbud.c |
| 20701 | 20699 | |
| 20702 | 20700 | ZD1211RW WIRELESS DRIVER |
| 20703 | −M: Daniel Drake <dsd@gentoo.org> | |
| 20704 | 20701 | M: Ulrich Kunitz <kune@deine-taler.de> |
| 20705 | 20702 | L: linux-wireless@vger.kernel.org |
| 20706 | 20703 | L: zd1211-devs@lists.sourceforge.net (subscribers-only) |
| @@ -36,6 +36,10 @@ · 35 unmodified lines | ||
| 36 | 36 | * +-----+ |
| 37 | 37 | * |RSVD | JIT scratchpad |
| 38 | 38 | * current ARM_SP => +-----+ <= (BPF_FP - STACK_SIZE + SCRATCH_SIZE) |
| 39 | + * | ... | caller-saved registers | |
| 40 | + * +-----+ | |
| 41 | + * | ... | arguments passed on stack | |
| 42 | + * ARM_SP during call => +-----| | |
| 39 | 43 | * | | |
| 40 | 44 | * | ... | Function call stack |
| 41 | 45 | * | | |
| @@ -63,6 +67,12 @@ · 21 unmodified lines | ||
| 63 | 67 | * |
| 64 | 68 | * When popping registers off the stack at the end of a BPF function, we |
| 65 | 69 | * reference them via the current ARM_FP register. |
| 70 | + * | |
| 71 | + * Some eBPF operations are implemented via a call to a helper function. | |
| 72 | + * Such calls are "invisible" in the eBPF code, so it is up to the calling | |
| 73 | + * program to preserve any caller-saved ARM registers during the call. The | |
| 74 | + * JIT emits code to push and pop those registers onto the stack, immediately | |
| 75 | + * above the callee stack frame. | |
| 66 | 76 | */ |
| 67 | 77 | #define CALLEE_MASK (1 << ARM_R4 | 1 << ARM_R5 | 1 << ARM_R6 | \ |
| 68 | 78 | 1 << ARM_R7 | 1 << ARM_R8 | 1 << ARM_R9 | \ |
| @@ -70,6 +80,8 @@ · 1 unmodified line | ||
| 70 | 80 | #define CALLEE_PUSH_MASK (CALLEE_MASK | 1 << ARM_LR) |
| 71 | 81 | #define CALLEE_POP_MASK (CALLEE_MASK | 1 << ARM_PC) |
| 72 | 82 | |
| 83 | +#define CALLER_MASK (1 << ARM_R0 | 1 << ARM_R1 | 1 << ARM_R2 | 1 << ARM_R3) | |
| 84 | + | |
| 73 | 85 | enum { |
| 74 | 86 | /* Stack layout - these are offsets from (top of stack - 4) */ |
| 75 | 87 | BPF_R2_HI, |
| @@ -464,6 +476,7 @@ static inline int epilogue_offset(const struct jit_ctx *ctx) · 388 unmodified lines | ||
| 464 | 476 | |
| 465 | 477 | static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) |
| 466 | 478 | { |
| 479 | + const int exclude_mask = BIT(ARM_R0) | BIT(ARM_R1); | |
| 467 | 480 | const s8 *tmp = bpf2a32[TMP_REG_1]; |
| 468 | 481 | |
| 469 | 482 | #if __LINUX_ARM_ARCH__ == 7 |
| @@ -495,11 +508,17 @@ static inline void emit_udivmod(u8 rd, u8 rm, u8 rn, struct jit_ctx *ctx, u8 op) · 25 unmodified lines | ||
| 495 | 508 | emit(ARM_MOV_R(ARM_R0, rm), ctx); |
| 496 | 509 | } |
| 497 | 510 | |
| 511 | + /* Push caller-saved registers on stack */ | |
| 512 | + emit(ARM_PUSH(CALLER_MASK & ~exclude_mask), ctx); | |
| 513 | + | |
| 498 | 514 | /* Call appropriate function */ |
| 499 | 515 | emit_mov_i(ARM_IP, op == BPF_DIV ? |
| 500 | 516 | (u32)jit_udiv32 : (u32)jit_mod32, ctx); |
| 501 | 517 | emit_blx_r(ARM_IP, ctx); |
| 502 | 518 | |
| 519 | + /* Restore caller-saved registers from stack */ | |
| 520 | + emit(ARM_POP(CALLER_MASK & ~exclude_mask), ctx); | |
| 521 | + | |
| 503 | 522 | /* Save return value */ |
| 504 | 523 | if (rd != ARM_R0) |
| 505 | 524 | emit(ARM_MOV_R(rd, ARM_R0), ctx); |
| @@ -154,7 +154,7 @@ · 153 unmodified lines | ||
| 154 | 154 | |
| 155 | 155 | fm1mac3: ethernet@e4000 { |
| 156 | 156 | phy-handle = <&sgmii_aqr_phy3>; |
| 157 | − phy-connection-type = "sgmii-2500"; | |
| 157 | + phy-connection-type = "2500base-x"; | |
| 158 | 158 | sleep = <&rcpm 0x20000000>; |
| 159 | 159 | }; |
| 160 | 160 | |
| @@ -780,7 +780,7 @@ struct gve_queue_page_list *gve_assign_rx_qpl(struct gve_priv *priv) · 779 unmodified lines | ||
| 780 | 780 | gve_num_tx_qpls(priv)); |
| 781 | 781 | |
| 782 | 782 | /* we are out of rx qpls */ |
| 783 | − if (id == priv->qpl_cfg.qpl_map_size) | |
| 783 | + if (id == gve_num_tx_qpls(priv) + gve_num_rx_qpls(priv)) | |
| 784 | 784 | return NULL; |
| 785 | 785 | |
| 786 | 786 | set_bit(id, priv->qpl_cfg.qpl_id_map); |
| @@ -41,6 +41,7 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) · 40 unmodified lines | ||
| 41 | 41 | { |
| 42 | 42 | struct gve_priv *priv = netdev_priv(dev); |
| 43 | 43 | unsigned int start; |
| 44 | + u64 packets, bytes; | |
| 44 | 45 | int ring; |
| 45 | 46 | |
| 46 | 47 | if (priv->rx) { |
| @@ -48,10 +49,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) · 1 unmodified line | ||
| 48 | 49 | do { |
| 49 | 50 | start = |
| 50 | 51 | u64_stats_fetch_begin(&priv->rx[ring].statss); |
| 51 | − s->rx_packets += priv->rx[ring].rpackets; | |
| 52 | − s->rx_bytes += priv->rx[ring].rbytes; | |
| 52 | + packets = priv->rx[ring].rpackets; | |
| 53 | + bytes = priv->rx[ring].rbytes; | |
| 53 | 54 | } while (u64_stats_fetch_retry(&priv->rx[ring].statss, |
| 54 | 55 | start)); |
| 56 | + s->rx_packets += packets; | |
| 57 | + s->rx_bytes += bytes; | |
| 55 | 58 | } |
| 56 | 59 | } |
| 57 | 60 | if (priv->tx) { |
| @@ -59,10 +62,12 @@ static void gve_get_stats(struct net_device *dev, struct rtnl_link_stats64 *s) · 1 unmodified line | ||
| 59 | 62 | do { |
| 60 | 63 | start = |
| 61 | 64 | u64_stats_fetch_begin(&priv->tx[ring].statss); |
| 62 | − s->tx_packets += priv->tx[ring].pkt_done; | |
| 63 | − s->tx_bytes += priv->tx[ring].bytes_done; | |
| 65 | + packets = priv->tx[ring].pkt_done; | |
| 66 | + bytes = priv->tx[ring].bytes_done; | |
| 64 | 67 | } while (u64_stats_fetch_retry(&priv->tx[ring].statss, |
| 65 | 68 | start)); |
| 69 | + s->tx_packets += packets; | |
| 70 | + s->tx_bytes += bytes; | |
| 66 | 71 | } |
| 67 | 72 | } |
| 68 | 73 | } |
| @@ -82,6 +87,9 @@ static int gve_alloc_counter_array(struct gve_priv *priv) · 13 unmodified lines | ||
| 82 | 87 | |
| 83 | 88 | static void gve_free_counter_array(struct gve_priv *priv) |
| 84 | 89 | { |
| 90 | + if (!priv->counter_array) | |
| 91 | + return; | |
| 92 | + | |
| 85 | 93 | dma_free_coherent(&priv->pdev->dev, |
| 86 | 94 | priv->num_event_counters * |
| 87 | 95 | sizeof(*priv->counter_array), |
| @@ -142,6 +150,9 @@ static int gve_alloc_stats_report(struct gve_priv *priv) · 54 unmodified lines | ||
| 142 | 150 | |
| 143 | 151 | static void gve_free_stats_report(struct gve_priv *priv) |
| 144 | 152 | { |
| 153 | + if (!priv->stats_report) | |
| 154 | + return; | |
| 155 | + | |
| 145 | 156 | del_timer_sync(&priv->stats_report_timer); |
| 146 | 157 | dma_free_coherent(&priv->pdev->dev, priv->stats_report_len, |
| 147 | 158 | priv->stats_report, priv->stats_report_bus); |
| @@ -370,18 +381,19 @@ static void gve_free_notify_blocks(struct gve_priv *priv) · 222 unmodified lines | ||
| 370 | 381 | { |
| 371 | 382 | int i; |
| 372 | 383 | |
| 373 | − if (priv->msix_vectors) { | |
| 374 | − /* Free the irqs */ | |
| 375 | − for (i = 0; i < priv->num_ntfy_blks; i++) { | |
| 376 | − struct gve_notify_block *block = &priv->ntfy_blocks[i]; | |
| 377 | − int msix_idx = i; | |
| 384 | + if (!priv->msix_vectors) | |
| 385 | + return; | |
| 378 | 386 | |
| 379 | − irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, | |
| 380 | − NULL); | |
| 381 | − free_irq(priv->msix_vectors[msix_idx].vector, block); | |
| 382 | − } | |
| 383 | − free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); | |
| 387 | + /* Free the irqs */ | |
| 388 | + for (i = 0; i < priv->num_ntfy_blks; i++) { | |
| 389 | + struct gve_notify_block *block = &priv->ntfy_blocks[i]; | |
| 390 | + int msix_idx = i; | |
| 391 | + | |
| 392 | + irq_set_affinity_hint(priv->msix_vectors[msix_idx].vector, | |
| 393 | + NULL); | |
| 394 | + free_irq(priv->msix_vectors[msix_idx].vector, block); | |
| 384 | 395 | } |
| 396 | + free_irq(priv->msix_vectors[priv->mgmt_msix_idx].vector, priv); | |
| 385 | 397 | dma_free_coherent(&priv->pdev->dev, |
| 386 | 398 | priv->num_ntfy_blks * sizeof(*priv->ntfy_blocks), |
| 387 | 399 | priv->ntfy_blocks, priv->ntfy_block_bus); |
| @@ -1185,9 +1197,10 @@ static void gve_handle_reset(struct gve_priv *priv) · 797 unmodified lines | ||
| 1185 | 1197 | |
| 1186 | 1198 | void gve_handle_report_stats(struct gve_priv *priv) |
| 1187 | 1199 | { |
| 1188 | − int idx, stats_idx = 0, tx_bytes; | |
| 1189 | − unsigned int start = 0; | |
| 1190 | 1200 | struct stats *stats = priv->stats_report->stats; |
| 1201 | + int idx, stats_idx = 0; | |
| 1202 | + unsigned int start = 0; | |
| 1203 | + u64 tx_bytes; | |
| 1191 | 1204 | |
| 1192 | 1205 | if (!gve_get_report_stats(priv)) |
| 1193 | 1206 | return; |
| @@ -104,8 +104,14 @@ static int gve_prefill_rx_pages(struct gve_rx_ring *rx) · 103 unmodified lines | ||
| 104 | 104 | if (!rx->data.page_info) |
| 105 | 105 | return -ENOMEM; |
| 106 | 106 | |
| 107 | − if (!rx->data.raw_addressing) | |
| 107 | + if (!rx->data.raw_addressing) { | |
| 108 | 108 | rx->data.qpl = gve_assign_rx_qpl(priv); |
| 109 | + if (!rx->data.qpl) { | |
| 110 | + kvfree(rx->data.page_info); | |
| 111 | + rx->data.page_info = NULL; | |
| 112 | + return -ENOMEM; | |
| 113 | + } | |
| 114 | + } | |
| 109 | 115 | for (i = 0; i < slots; i++) { |
| 110 | 116 | if (!rx->data.raw_addressing) { |
| 111 | 117 | struct page *page = rx->data.qpl->pages[i]; |
| @@ -4871,7 +4871,8 @@ static void i40e_clear_interrupt_scheme(struct i40e_pf *pf) · 4870 unmodified lines | ||
| 4871 | 4871 | { |
| 4872 | 4872 | int i; |
| 4873 | 4873 | |
| 4874 | − i40e_free_misc_vector(pf); | |
| 4874 | + if (test_bit(__I40E_MISC_IRQ_REQUESTED, pf->state)) | |
| 4875 | + i40e_free_misc_vector(pf); | |
| 4875 | 4876 | |
| 4876 | 4877 | i40e_put_lump(pf->irq_pile, pf->iwarp_base_vector, |
| 4877 | 4878 | I40E_IWARP_IRQ_PILE_ID); |
| @@ -10113,7 +10114,7 @@ static int i40e_get_capabilities(struct i40e_pf *pf, · 5235 unmodified lines | ||
| 10113 | 10114 | if (pf->hw.aq.asq_last_status == I40E_AQ_RC_ENOMEM) { |
| 10114 | 10115 | /* retry with a larger buffer */ |
| 10115 | 10116 | buf_len = data_size; |
| 10116 | − } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK) { | |
| 10117 | + } else if (pf->hw.aq.asq_last_status != I40E_AQ_RC_OK || err) { | |
| 10117 | 10118 | dev_info(&pf->pdev->dev, |
| 10118 | 10119 | "capability discovery failed, err %s aq_err %s\n", |
| 10119 | 10120 | i40e_stat_str(&pf->hw, err), |
| @@ -1965,7 +1965,6 @@ static void iavf_watchdog_task(struct work_struct *work) · 1964 unmodified lines | ||
| 1965 | 1965 | } |
| 1966 | 1966 | adapter->aq_required = 0; |
| 1967 | 1967 | adapter->current_op = VIRTCHNL_OP_UNKNOWN; |
| 1968 | − mutex_unlock(&adapter->crit_lock); | |
| 1969 | 1968 | queue_delayed_work(iavf_wq, |
| 1970 | 1969 | &adapter->watchdog_task, |
| 1971 | 1970 | msecs_to_jiffies(10)); |
| @@ -252,6 +252,7 @@ struct mlx5e_params { · 251 unmodified lines | ||
| 252 | 252 | struct { |
| 253 | 253 | u16 mode; |
| 254 | 254 | u8 num_tc; |
| 255 | + struct netdev_tc_txq tc_to_txq[TC_MAX_QUEUE]; | |
| 255 | 256 | } mqprio; |
| 256 | 257 | bool rx_cqe_compress_def; |
| 257 | 258 | bool tunneled_offload_en; |
| @@ -845,6 +846,7 @@ struct mlx5e_priv { · 587 unmodified lines | ||
| 845 | 846 | struct mlx5e_channel_stats channel_stats[MLX5E_MAX_NUM_CHANNELS]; |
| 846 | 847 | struct mlx5e_channel_stats trap_stats; |
| 847 | 848 | struct mlx5e_ptp_stats ptp_stats; |
| 849 | + u16 stats_nch; | |
| 848 | 850 | u16 max_nch; |
| 849 | 851 | u8 max_opened_tc; |
| 850 | 852 | bool tx_ptp_opened; |
| @@ -1100,12 +1102,6 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv, · 249 unmodified lines | ||
| 1100 | 1102 | struct ethtool_pauseparam *pauseparam); |
| 1101 | 1103 | |
| 1102 | 1104 | /* mlx5e generic netdev management API */ |
| 1103 | −static inline unsigned int | |
| 1104 | −mlx5e_calc_max_nch(struct mlx5e_priv *priv, const struct mlx5e_profile *profile) | |
| 1105 | −{ | |
| 1106 | − return priv->netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1); | |
| 1107 | −} | |
| 1108 | − | |
| 1109 | 1105 | static inline bool |
| 1110 | 1106 | mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) |
| 1111 | 1107 | { |
| @@ -1114,11 +1110,13 @@ mlx5e_tx_mpwqe_supported(struct mlx5_core_dev *mdev) · 2 unmodified lines | ||
| 1114 | 1110 | } |
| 1115 | 1111 | |
| 1116 | 1112 | int mlx5e_priv_init(struct mlx5e_priv *priv, |
| 1113 | + const struct mlx5e_profile *profile, | |
| 1117 | 1114 | struct net_device *netdev, |
| 1118 | 1115 | struct mlx5_core_dev *mdev); |
| 1119 | 1116 | void mlx5e_priv_cleanup(struct mlx5e_priv *priv); |
| 1120 | 1117 | struct net_device * |
| 1121 | −mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs); | |
| 1118 | +mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, | |
| 1119 | + unsigned int txqs, unsigned int rxqs); | |
| 1122 | 1120 | int mlx5e_attach_netdev(struct mlx5e_priv *priv); |
| 1123 | 1121 | void mlx5e_detach_netdev(struct mlx5e_priv *priv); |
| 1124 | 1122 | void mlx5e_destroy_netdev(struct mlx5e_priv *priv); |
| @@ -35,7 +35,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data, · 34 unmodified lines | ||
| 35 | 35 | { |
| 36 | 36 | int ch, i = 0; |
| 37 | 37 | |
| 38 | − for (ch = 0; ch < priv->max_nch; ch++) { | |
| 38 | + for (ch = 0; ch < priv->stats_nch; ch++) { | |
| 39 | 39 | void *buf = data + i; |
| 40 | 40 | |
| 41 | 41 | if (WARN_ON_ONCE(buf + |
| @@ -51,7 +51,7 @@ static void mlx5e_hv_vhca_fill_stats(struct mlx5e_priv *priv, void *data, · 9 unmodified lines | ||
| 51 | 51 | static int mlx5e_hv_vhca_stats_buf_size(struct mlx5e_priv *priv) |
| 52 | 52 | { |
| 53 | 53 | return (sizeof(struct mlx5e_hv_vhca_per_ring_stats) * |
| 54 | − priv->max_nch); | |
| 54 | + priv->stats_nch); | |
| 55 | 55 | } |
| 56 | 56 | |
| 57 | 57 | static void mlx5e_hv_vhca_stats_work(struct work_struct *work) |
| @@ -100,7 +100,7 @@ static void mlx5e_hv_vhca_stats_control(struct mlx5_hv_vhca_agent *agent, · 42 unmodified lines | ||
| 100 | 100 | sagent = &priv->stats_agent; |
| 101 | 101 | |
| 102 | 102 | block->version = MLX5_HV_VHCA_STATS_VERSION; |
| 103 | − block->rings = priv->max_nch; | |
| 103 | + block->rings = priv->stats_nch; | |
| 104 | 104 | |
| 105 | 105 | if (!block->command) { |
| 106 | 106 | cancel_delayed_work_sync(&priv->stats_agent.work); |
| @@ -13,8 +13,6 @@ struct mlx5e_ptp_fs { · 12 unmodified lines | ||
| 13 | 13 | bool valid; |
| 14 | 14 | }; |
| 15 | 15 | |
| 16 | −#define MLX5E_PTP_CHANNEL_IX 0 | |
| 17 | − | |
| 18 | 16 | struct mlx5e_ptp_params { |
| 19 | 17 | struct mlx5e_params params; |
| 20 | 18 | struct mlx5e_sq_param txq_sq_param; |
| @@ -509,6 +507,7 @@ static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params, · 488 unmodified lines | ||
| 509 | 507 | rq->mdev = mdev; |
| 510 | 508 | rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); |
| 511 | 509 | rq->stats = &c->priv->ptp_stats.rq; |
| 510 | + rq->ix = MLX5E_PTP_CHANNEL_IX; | |
| 512 | 511 | rq->ptp_cyc2time = mlx5_rq_ts_translator(mdev); |
| 513 | 512 | err = mlx5e_rq_set_handlers(rq, params, false); |
| 514 | 513 | if (err) |
| @@ -8,6 +8,8 @@ · 7 unmodified lines | ||
| 8 | 8 | #include "en_stats.h" |
| 9 | 9 | #include <linux/ptp_classify.h> |
| 10 | 10 | |
| 11 | +#define MLX5E_PTP_CHANNEL_IX 0 | |
| 12 | + | |
| 11 | 13 | struct mlx5e_ptpsq { |
| 12 | 14 | struct mlx5e_txqsq txqsq; |
| 13 | 15 | struct mlx5e_cq ts_cq; |
| @@ -2036,6 +2036,17 @@ static int set_pflag_tx_port_ts(struct net_device *netdev, bool enable) · 2035 unmodified lines | ||
| 2036 | 2036 | } |
| 2037 | 2037 | |
| 2038 | 2038 | new_params = priv->channels.params; |
| 2039 | + /* Don't allow enabling TX-port-TS if MQPRIO mode channel offload is | |
| 2040 | + * active, since it defines explicitly which TC accepts the packet. | |
| 2041 | + * This conflicts with TX-port-TS hijacking the PTP traffic to a specific | |
| 2042 | + * HW TX-queue. | |
| 2043 | + */ | |
| 2044 | + if (enable && new_params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) { | |
| 2045 | + netdev_err(priv->netdev, | |
| 2046 | + "%s: MQPRIO mode channel offload is active, cannot set the TX-port-TS\n", | |
| 2047 | + __func__); | |
| 2048 | + return -EINVAL; | |
| 2049 | + } | |
| 2039 | 2050 | MLX5E_SET_PFLAG(&new_params, MLX5E_PFLAG_TX_PORT_TS, enable); |
| 2040 | 2051 | /* No need to verify SQ stop room as |
| 2041 | 2052 | * ptpsq.txqsq.stop_room <= generic_sq->stop_room, and both |
| @@ -2264,7 +2264,7 @@ void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv) · 2263 unmodified lines | ||
| 2264 | 2264 | } |
| 2265 | 2265 | |
| 2266 | 2266 | static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc, |
| 2267 | − struct tc_mqprio_qopt_offload *mqprio) | |
| 2267 | + struct netdev_tc_txq *tc_to_txq) | |
| 2268 | 2268 | { |
| 2269 | 2269 | int tc, err; |
| 2270 | 2270 | |
| @@ -2282,11 +2282,8 @@ static int mlx5e_netdev_set_tcs(struct net_device *netdev, u16 nch, u8 ntc, · 11 unmodified lines | ||
| 2282 | 2282 | for (tc = 0; tc < ntc; tc++) { |
| 2283 | 2283 | u16 count, offset; |
| 2284 | 2284 | |
| 2285 | − /* For DCB mode, map netdev TCs to offset 0 | |
| 2286 | − * We have our own UP to TXQ mapping for QoS | |
| 2287 | − */ | |
| 2288 | − count = mqprio ? mqprio->qopt.count[tc] : nch; | |
| 2289 | − offset = mqprio ? mqprio->qopt.offset[tc] : 0; | |
| 2285 | + count = tc_to_txq[tc].count; | |
| 2286 | + offset = tc_to_txq[tc].offset; | |
| 2290 | 2287 | netdev_set_tc_queue(netdev, tc, count, offset); |
| 2291 | 2288 | } |
| 2292 | 2289 | |
| @@ -2315,19 +2312,24 @@ int mlx5e_update_tx_netdev_queues(struct mlx5e_priv *priv) · 22 unmodified lines | ||
| 2315 | 2312 | |
| 2316 | 2313 | static int mlx5e_update_netdev_queues(struct mlx5e_priv *priv) |
| 2317 | 2314 | { |
| 2315 | + struct netdev_tc_txq old_tc_to_txq[TC_MAX_QUEUE], *tc_to_txq; | |
| 2318 | 2316 | struct net_device *netdev = priv->netdev; |
| 2319 | 2317 | int old_num_txqs, old_ntc; |
| 2320 | 2318 | int num_rxqs, nch, ntc; |
| 2321 | 2319 | int err; |
| 2320 | + int i; | |
| 2322 | 2321 | |
| 2323 | 2322 | old_num_txqs = netdev->real_num_tx_queues; |
| 2324 | 2323 | old_ntc = netdev->num_tc ? : 1; |
| 2324 | + for (i = 0; i < ARRAY_SIZE(old_tc_to_txq); i++) | |
| 2325 | + old_tc_to_txq[i] = netdev->tc_to_txq[i]; | |
| 2325 | 2326 | |
| 2326 | 2327 | nch = priv->channels.params.num_channels; |
| 2327 | − ntc = mlx5e_get_dcb_num_tc(&priv->channels.params); | |
| 2328 | + ntc = priv->channels.params.mqprio.num_tc; | |
| 2328 | 2329 | num_rxqs = nch * priv->profile->rq_groups; |
| 2330 | + tc_to_txq = priv->channels.params.mqprio.tc_to_txq; | |
| 2329 | 2331 | |
| 2330 | − err = mlx5e_netdev_set_tcs(netdev, nch, ntc, NULL); | |
| 2332 | + err = mlx5e_netdev_set_tcs(netdev, nch, ntc, tc_to_txq); | |
| 2331 | 2333 | if (err) |
| 2332 | 2334 | goto err_out; |
| 2333 | 2335 | err = mlx5e_update_tx_netdev_queues(priv); |
| @@ -2350,11 +2352,14 @@ err_txqs: · 16 unmodified lines | ||
| 2350 | 2352 | WARN_ON_ONCE(netif_set_real_num_tx_queues(netdev, old_num_txqs)); |
| 2351 | 2353 | |
| 2352 | 2354 | err_tcs: |
| 2353 | − mlx5e_netdev_set_tcs(netdev, old_num_txqs / old_ntc, old_ntc, NULL); | |
| 2355 | + WARN_ON_ONCE(mlx5e_netdev_set_tcs(netdev, old_num_txqs / old_ntc, old_ntc, | |
| 2356 | + old_tc_to_txq)); | |
| 2354 | 2357 | err_out: |
| 2355 | 2358 | return err; |
| 2356 | 2359 | } |
| 2357 | 2360 | |
| 2361 | +static MLX5E_DEFINE_PREACTIVATE_WRAPPER_CTX(mlx5e_update_netdev_queues); | |
| 2362 | + | |
| 2358 | 2363 | static void mlx5e_set_default_xps_cpumasks(struct mlx5e_priv *priv, |
| 2359 | 2364 | struct mlx5e_params *params) |
| 2360 | 2365 | { |
| @@ -2861,6 +2866,58 @@ static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd) · 500 unmodified lines | ||
| 2861 | 2866 | return 0; |
| 2862 | 2867 | } |
| 2863 | 2868 | |
| 2869 | +static void mlx5e_mqprio_build_default_tc_to_txq(struct netdev_tc_txq *tc_to_txq, | |
| 2870 | + int ntc, int nch) | |
| 2871 | +{ | |
| 2872 | + int tc; | |
| 2873 | + | |
| 2874 | + memset(tc_to_txq, 0, sizeof(*tc_to_txq) * TC_MAX_QUEUE); | |
| 2875 | + | |
| 2876 | + /* Map netdev TCs to offset 0. | |
| 2877 | + * We have our own UP to TXQ mapping for DCB mode of QoS | |
| 2878 | + */ | |
| 2879 | + for (tc = 0; tc < ntc; tc++) { | |
| 2880 | + tc_to_txq[tc] = (struct netdev_tc_txq) { | |
| 2881 | + .count = nch, | |
| 2882 | + .offset = 0, | |
| 2883 | + }; | |
| 2884 | + } | |
| 2885 | +} | |
| 2886 | + | |
| 2887 | +static void mlx5e_mqprio_build_tc_to_txq(struct netdev_tc_txq *tc_to_txq, | |
| 2888 | + struct tc_mqprio_qopt *qopt) | |
| 2889 | +{ | |
| 2890 | + int tc; | |
| 2891 | + | |
| 2892 | + for (tc = 0; tc < TC_MAX_QUEUE; tc++) { | |
| 2893 | + tc_to_txq[tc] = (struct netdev_tc_txq) { | |
| 2894 | + .count = qopt->count[tc], | |
| 2895 | + .offset = qopt->offset[tc], | |
| 2896 | + }; | |
| 2897 | + } | |
| 2898 | +} | |
| 2899 | + | |
| 2900 | +static void mlx5e_params_mqprio_dcb_set(struct mlx5e_params *params, u8 num_tc) | |
| 2901 | +{ | |
| 2902 | + params->mqprio.mode = TC_MQPRIO_MODE_DCB; | |
| 2903 | + params->mqprio.num_tc = num_tc; | |
| 2904 | + mlx5e_mqprio_build_default_tc_to_txq(params->mqprio.tc_to_txq, num_tc, | |
| 2905 | + params->num_channels); | |
| 2906 | +} | |
| 2907 | + | |
| 2908 | +static void mlx5e_params_mqprio_channel_set(struct mlx5e_params *params, | |
| 2909 | + struct tc_mqprio_qopt *qopt) | |
| 2910 | +{ | |
| 2911 | + params->mqprio.mode = TC_MQPRIO_MODE_CHANNEL; | |
| 2912 | + params->mqprio.num_tc = qopt->num_tc; | |
| 2913 | + mlx5e_mqprio_build_tc_to_txq(params->mqprio.tc_to_txq, qopt); | |
| 2914 | +} | |
| 2915 | + | |
| 2916 | +static void mlx5e_params_mqprio_reset(struct mlx5e_params *params) | |
| 2917 | +{ | |
| 2918 | + mlx5e_params_mqprio_dcb_set(params, 1); | |
| 2919 | +} | |
| 2920 | + | |
| 2864 | 2921 | static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv, |
| 2865 | 2922 | struct tc_mqprio_qopt *mqprio) |
| 2866 | 2923 | { |
| @@ -2874,8 +2931,7 @@ static int mlx5e_setup_tc_mqprio_dcb(struct mlx5e_priv *priv, · 7 unmodified lines | ||
| 2874 | 2931 | return -EINVAL; |
| 2875 | 2932 | |
| 2876 | 2933 | new_params = priv->channels.params; |
| 2877 | − new_params.mqprio.mode = TC_MQPRIO_MODE_DCB; | |
| 2878 | − new_params.mqprio.num_tc = tc ? tc : 1; | |
| 2934 | + mlx5e_params_mqprio_dcb_set(&new_params, tc ? tc : 1); | |
| 2879 | 2935 | |
| 2880 | 2936 | err = mlx5e_safe_switch_params(priv, &new_params, |
| 2881 | 2937 | mlx5e_num_channels_changed_ctx, NULL, true); |
| @@ -2889,9 +2945,17 @@ static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv, · 7 unmodified lines | ||
| 2889 | 2945 | struct tc_mqprio_qopt_offload *mqprio) |
| 2890 | 2946 | { |
| 2891 | 2947 | struct net_device *netdev = priv->netdev; |
| 2948 | + struct mlx5e_ptp *ptp_channel; | |
| 2892 | 2949 | int agg_count = 0; |
| 2893 | 2950 | int i; |
| 2894 | 2951 | |
| 2952 | + ptp_channel = priv->channels.ptp; | |
| 2953 | + if (ptp_channel && test_bit(MLX5E_PTP_STATE_TX, ptp_channel->state)) { | |
| 2954 | + netdev_err(netdev, | |
| 2955 | + "Cannot activate MQPRIO mode channel since it conflicts with TX port TS\n"); | |
| 2956 | + return -EINVAL; | |
| 2957 | + } | |
| 2958 | + | |
| 2895 | 2959 | if (mqprio->qopt.offset[0] != 0 || mqprio->qopt.num_tc < 1 || |
| 2896 | 2960 | mqprio->qopt.num_tc > MLX5E_MAX_NUM_MQPRIO_CH_TC) |
| 2897 | 2961 | return -EINVAL; |
| @@ -2926,25 +2990,12 @@ static int mlx5e_mqprio_channel_validate(struct mlx5e_priv *priv, · 28 unmodified lines | ||
| 2926 | 2990 | return 0; |
| 2927 | 2991 | } |
| 2928 | 2992 | |
| 2929 | −static int mlx5e_mqprio_channel_set_tcs_ctx(struct mlx5e_priv *priv, void *ctx) | |
| 2930 | −{ | |
| 2931 | − struct tc_mqprio_qopt_offload *mqprio = (struct tc_mqprio_qopt_offload *)ctx; | |
| 2932 | − struct net_device *netdev = priv->netdev; | |
| 2933 | − u8 num_tc; | |
| 2934 | − | |
| 2935 | − if (priv->channels.params.mqprio.mode != TC_MQPRIO_MODE_CHANNEL) | |
| 2936 | − return -EINVAL; | |
| 2937 | − | |
| 2938 | − num_tc = priv->channels.params.mqprio.num_tc; | |
| 2939 | − mlx5e_netdev_set_tcs(netdev, 0, num_tc, mqprio); | |
| 2940 | − | |
| 2941 | − return 0; | |
| 2942 | −} | |
| 2943 | − | |
| 2944 | 2993 | static int mlx5e_setup_tc_mqprio_channel(struct mlx5e_priv *priv, |
| 2945 | 2994 | struct tc_mqprio_qopt_offload *mqprio) |
| 2946 | 2995 | { |
| 2996 | + mlx5e_fp_preactivate preactivate; | |
| 2947 | 2997 | struct mlx5e_params new_params; |
| 2998 | + bool nch_changed; | |
| 2948 | 2999 | int err; |
| 2949 | 3000 | |
| 2950 | 3001 | err = mlx5e_mqprio_channel_validate(priv, mqprio); |
| @@ -2952,12 +3003,12 @@ static int mlx5e_setup_tc_mqprio_channel(struct mlx5e_priv *priv, · 1 unmodified line | ||
| 2952 | 3003 | return err; |
| 2953 | 3004 | |
| 2954 | 3005 | new_params = priv->channels.params; |
| 2955 | − new_params.mqprio.mode = TC_MQPRIO_MODE_CHANNEL; | |
| 2956 | − new_params.mqprio.num_tc = mqprio->qopt.num_tc; | |
| 2957 | − err = mlx5e_safe_switch_params(priv, &new_params, | |
| 2958 | − mlx5e_mqprio_channel_set_tcs_ctx, mqprio, true); | |
| 3006 | + mlx5e_params_mqprio_channel_set(&new_params, &mqprio->qopt); | |
| 2959 | 3007 | |
| 2960 | − return err; | |
| 3008 | + nch_changed = mlx5e_get_dcb_num_tc(&priv->channels.params) > 1; | |
| 3009 | + preactivate = nch_changed ? mlx5e_num_channels_changed_ctx : | |
| 3010 | + mlx5e_update_netdev_queues_ctx; | |
| 3011 | + return mlx5e_safe_switch_params(priv, &new_params, preactivate, NULL, true); | |
| 2961 | 3012 | } |
| 2962 | 3013 | |
| 2963 | 3014 | static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv, |
| @@ -3065,7 +3116,7 @@ void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s) · 101 unmodified lines | ||
| 3065 | 3116 | { |
| 3066 | 3117 | int i; |
| 3067 | 3118 | |
| 3068 | − for (i = 0; i < priv->max_nch; i++) { | |
| 3119 | + for (i = 0; i < priv->stats_nch; i++) { | |
| 3069 | 3120 | struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i]; |
| 3070 | 3121 | struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq; |
| 3071 | 3122 | struct mlx5e_rq_stats *rq_stats = &channel_stats->rq; |
| @@ -4186,13 +4237,11 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 · 1114 unmodified lines | ||
| 4186 | 4237 | struct mlx5_core_dev *mdev = priv->mdev; |
| 4187 | 4238 | u8 rx_cq_period_mode; |
| 4188 | 4239 | |
| 4189 | − priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile); | |
| 4190 | − | |
| 4191 | 4240 | params->sw_mtu = mtu; |
| 4192 | 4241 | params->hard_mtu = MLX5E_ETH_HARD_MTU; |
| 4193 | 4242 | params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2, |
| 4194 | 4243 | priv->max_nch); |
| 4195 | − params->mqprio.num_tc = 1; | |
| 4244 | + mlx5e_params_mqprio_reset(params); | |
| 4196 | 4245 | |
| 4197 | 4246 | /* Set an initial non-zero value, so that mlx5e_select_queue won't |
| 4198 | 4247 | * divide by zero if called before first activating channels. |
| @@ -4682,8 +4731,35 @@ static const struct mlx5e_profile mlx5e_nic_profile = { · 483 unmodified lines | ||
| 4682 | 4731 | .rx_ptp_support = true, |
| 4683 | 4732 | }; |
| 4684 | 4733 | |
| 4734 | +static unsigned int | |
| 4735 | +mlx5e_calc_max_nch(struct mlx5_core_dev *mdev, struct net_device *netdev, | |
| 4736 | + const struct mlx5e_profile *profile) | |
| 4737 | + | |
| 4738 | +{ | |
| 4739 | + unsigned int max_nch, tmp; | |
| 4740 | + | |
| 4741 | + /* core resources */ | |
| 4742 | + max_nch = mlx5e_get_max_num_channels(mdev); | |
| 4743 | + | |
| 4744 | + /* netdev rx queues */ | |
| 4745 | + tmp = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1); | |
| 4746 | + max_nch = min_t(unsigned int, max_nch, tmp); | |
| 4747 | + | |
| 4748 | + /* netdev tx queues */ | |
| 4749 | + tmp = netdev->num_tx_queues; | |
| 4750 | + if (mlx5_qos_is_supported(mdev)) | |
| 4751 | + tmp -= mlx5e_qos_max_leaf_nodes(mdev); | |
| 4752 | + if (MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn)) | |
| 4753 | + tmp -= profile->max_tc; | |
| 4754 | + tmp = tmp / profile->max_tc; | |
| 4755 | + max_nch = min_t(unsigned int, max_nch, tmp); | |
| 4756 | + | |
| 4757 | + return max_nch; | |
| 4758 | +} | |
| 4759 | + | |
| 4685 | 4760 | /* mlx5e generic netdev management API (move to en_common.c) */ |
| 4686 | 4761 | int mlx5e_priv_init(struct mlx5e_priv *priv, |
| 4762 | + const struct mlx5e_profile *profile, | |
| 4687 | 4763 | struct net_device *netdev, |
| 4688 | 4764 | struct mlx5_core_dev *mdev) |
| 4689 | 4765 | { |
| @@ -4691,6 +4767,8 @@ int mlx5e_priv_init(struct mlx5e_priv *priv, · 1 unmodified line | ||
| 4691 | 4767 | priv->mdev = mdev; |
| 4692 | 4768 | priv->netdev = netdev; |
| 4693 | 4769 | priv->msglevel = MLX5E_MSG_LEVEL; |
| 4770 | + priv->max_nch = mlx5e_calc_max_nch(mdev, netdev, profile); | |
| 4771 | + priv->stats_nch = priv->max_nch; | |
| 4694 | 4772 | priv->max_opened_tc = 1; |
| 4695 | 4773 | |
| 4696 | 4774 | if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL)) |
| @@ -4734,7 +4812,8 @@ void mlx5e_priv_cleanup(struct mlx5e_priv *priv) · 37 unmodified lines | ||
| 4734 | 4812 | } |
| 4735 | 4813 | |
| 4736 | 4814 | struct net_device * |
| 4737 | −mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs) | |
| 4815 | +mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, | |
| 4816 | + unsigned int txqs, unsigned int rxqs) | |
| 4738 | 4817 | { |
| 4739 | 4818 | struct net_device *netdev; |
| 4740 | 4819 | int err; |
| @@ -4745,7 +4824,7 @@ mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int · 4 unmodified lines | ||
| 4745 | 4824 | return NULL; |
| 4746 | 4825 | } |
| 4747 | 4826 | |
| 4748 | − err = mlx5e_priv_init(netdev_priv(netdev), netdev, mdev); | |
| 4827 | + err = mlx5e_priv_init(netdev_priv(netdev), profile, netdev, mdev); | |
| 4749 | 4828 | if (err) { |
| 4750 | 4829 | mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); |
| 4751 | 4830 | goto err_free_netdev; |
| @@ -4787,7 +4866,7 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) · 35 unmodified lines | ||
| 4787 | 4866 | clear_bit(MLX5E_STATE_DESTROYING, &priv->state); |
| 4788 | 4867 | |
| 4789 | 4868 | /* max number of channels may have changed */ |
| 4790 | − max_nch = mlx5e_get_max_num_channels(priv->mdev); | |
| 4869 | + max_nch = mlx5e_calc_max_nch(priv->mdev, priv->netdev, profile); | |
| 4791 | 4870 | if (priv->channels.params.num_channels > max_nch) { |
| 4792 | 4871 | mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch); |
| 4793 | 4872 | /* Reducing the number of channels - RXFH has to be reset, and |
| @@ -4795,7 +4874,18 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) · 1 unmodified line | ||
| 4795 | 4874 | */ |
| 4796 | 4875 | priv->netdev->priv_flags &= ~IFF_RXFH_CONFIGURED; |
| 4797 | 4876 | priv->channels.params.num_channels = max_nch; |
| 4877 | + if (priv->channels.params.mqprio.mode == TC_MQPRIO_MODE_CHANNEL) { | |
| 4878 | + mlx5_core_warn(priv->mdev, "MLX5E: Disabling MQPRIO channel mode\n"); | |
| 4879 | + mlx5e_params_mqprio_reset(&priv->channels.params); | |
| 4880 | + } | |
| 4798 | 4881 | } |
| 4882 | + if (max_nch != priv->max_nch) { | |
| 4883 | + mlx5_core_warn(priv->mdev, | |
| 4884 | + "MLX5E: Updating max number of channels from %u to %u\n", | |
| 4885 | + priv->max_nch, max_nch); | |
| 4886 | + priv->max_nch = max_nch; | |
| 4887 | + } | |
| 4888 | + | |
| 4799 | 4889 | /* 1. Set the real number of queues in the kernel the first time. |
| 4800 | 4890 | * 2. Set our default XPS cpumask. |
| 4801 | 4891 | * 3. Build the RQT. |
| @@ -4860,7 +4950,7 @@ mlx5e_netdev_attach_profile(struct net_device *netdev, struct mlx5_core_dev *mde · 58 unmodified lines | ||
| 4860 | 4950 | struct mlx5e_priv *priv = netdev_priv(netdev); |
| 4861 | 4951 | int err; |
| 4862 | 4952 | |
| 4863 | − err = mlx5e_priv_init(priv, netdev, mdev); | |
| 4953 | + err = mlx5e_priv_init(priv, new_profile, netdev, mdev); | |
| 4864 | 4954 | if (err) { |
| 4865 | 4955 | mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err); |
| 4866 | 4956 | return err; |
| @@ -4886,20 +4976,12 @@ priv_cleanup: · 19 unmodified lines | ||
| 4886 | 4976 | int mlx5e_netdev_change_profile(struct mlx5e_priv *priv, |
| 4887 | 4977 | const struct mlx5e_profile *new_profile, void *new_ppriv) |
| 4888 | 4978 | { |
| 4889 | − unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile); | |
| 4890 | 4979 | const struct mlx5e_profile *orig_profile = priv->profile; |
| 4891 | 4980 | struct net_device *netdev = priv->netdev; |
| 4892 | 4981 | struct mlx5_core_dev *mdev = priv->mdev; |
| 4893 | 4982 | void *orig_ppriv = priv->ppriv; |
| 4894 | 4983 | int err, rollback_err; |
| 4895 | 4984 | |
| 4896 | − /* sanity */ | |
| 4897 | − if (new_max_nch != priv->max_nch) { | |
| 4898 | − netdev_warn(netdev, "%s: Replacing profile with different max channels\n", | |
| 4899 | − __func__); | |
| 4900 | − return -EINVAL; | |
| 4901 | − } | |
| 4902 | − | |
| 4903 | 4985 | /* cleanup old profile */ |
| 4904 | 4986 | mlx5e_detach_netdev(priv); |
| 4905 | 4987 | priv->profile->cleanup(priv); |
| @@ -4995,7 +5077,7 @@ static int mlx5e_probe(struct auxiliary_device *adev, · 89 unmodified lines | ||
| 4995 | 5077 | nch = mlx5e_get_max_num_channels(mdev); |
| 4996 | 5078 | txqs = nch * profile->max_tc + ptp_txqs + qos_sqs; |
| 4997 | 5079 | rxqs = nch * profile->rq_groups; |
| 4998 | − netdev = mlx5e_create_netdev(mdev, txqs, rxqs); | |
| 5080 | + netdev = mlx5e_create_netdev(mdev, profile, txqs, rxqs); | |
| 4999 | 5081 | if (!netdev) { |
| 5000 | 5082 | mlx5_core_err(mdev, "mlx5e_create_netdev failed\n"); |
| 5001 | 5083 | return -ENOMEM; |
| @@ -596,7 +596,6 @@ static void mlx5e_build_rep_params(struct net_device *netdev) · 595 unmodified lines | ||
| 596 | 596 | MLX5_CQ_PERIOD_MODE_START_FROM_CQE : |
| 597 | 597 | MLX5_CQ_PERIOD_MODE_START_FROM_EQE; |
| 598 | 598 | |
| 599 | − priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile); | |
| 600 | 599 | params = &priv->channels.params; |
| 601 | 600 | |
| 602 | 601 | params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS; |
| @@ -1169,7 +1168,7 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) · 566 unmodified lines | ||
| 1169 | 1168 | nch = mlx5e_get_max_num_channels(dev); |
| 1170 | 1169 | txqs = nch * profile->max_tc; |
| 1171 | 1170 | rxqs = nch * profile->rq_groups; |
| 1172 | − netdev = mlx5e_create_netdev(dev, txqs, rxqs); | |
| 1171 | + netdev = mlx5e_create_netdev(dev, profile, txqs, rxqs); | |
| 1173 | 1172 | if (!netdev) { |
| 1174 | 1173 | mlx5_core_warn(dev, |
| 1175 | 1174 | "Failed to create representor netdev for vport %d\n", |
| @@ -1001,14 +1001,9 @@ static inline void mlx5e_handle_csum(struct net_device *netdev, · 1000 unmodified lines | ||
| 1001 | 1001 | goto csum_unnecessary; |
| 1002 | 1002 | |
| 1003 | 1003 | if (likely(is_last_ethertype_ip(skb, &network_depth, &proto))) { |
| 1004 | − u8 ipproto = get_ip_proto(skb, network_depth, proto); | |
| 1005 | − | |
| 1006 | − if (unlikely(ipproto == IPPROTO_SCTP)) | |
| 1004 | + if (unlikely(get_ip_proto(skb, network_depth, proto) == IPPROTO_SCTP)) | |
| 1007 | 1005 | goto csum_unnecessary; |
| 1008 | 1006 | |
| 1009 | − if (unlikely(mlx5_ipsec_is_rx_flow(cqe))) | |
| 1010 | − goto csum_none; | |
| 1011 | − | |
| 1012 | 1007 | stats->csum_complete++; |
| 1013 | 1008 | skb->ip_summed = CHECKSUM_COMPLETE; |
| 1014 | 1009 | skb->csum = csum_unfold((__force __sum16)cqe->check_sum); |
| @@ -34,6 +34,7 @@ · 33 unmodified lines | ||
| 34 | 34 | #include "en.h" |
| 35 | 35 | #include "en_accel/tls.h" |
| 36 | 36 | #include "en_accel/en_accel.h" |
| 37 | +#include "en/ptp.h" | |
| 37 | 38 | |
| 38 | 39 | static unsigned int stats_grps_num(struct mlx5e_priv *priv) |
| 39 | 40 | { |
| @@ -450,7 +451,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(sw) · 410 unmodified lines | ||
| 450 | 451 | |
| 451 | 452 | memset(s, 0, sizeof(*s)); |
| 452 | 453 | |
| 453 | − for (i = 0; i < priv->max_nch; i++) { | |
| 454 | + for (i = 0; i < priv->stats_nch; i++) { | |
| 454 | 455 | struct mlx5e_channel_stats *channel_stats = |
| 455 | 456 | &priv->channel_stats[i]; |
| 456 | 457 | int j; |
| @@ -2076,7 +2077,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(ptp) · 1619 unmodified lines | ||
| 2076 | 2077 | if (priv->rx_ptp_opened) { |
| 2077 | 2078 | for (i = 0; i < NUM_PTP_RQ_STATS; i++) |
| 2078 | 2079 | sprintf(data + (idx++) * ETH_GSTRING_LEN, |
| 2079 | − ptp_rq_stats_desc[i].format); | |
| 2080 | + ptp_rq_stats_desc[i].format, MLX5E_PTP_CHANNEL_IX); | |
| 2080 | 2081 | } |
| 2081 | 2082 | return idx; |
| 2082 | 2083 | } |
| @@ -2119,7 +2120,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_UPDATE_STATS(ptp) { return; } · 36 unmodified lines | ||
| 2119 | 2120 | |
| 2120 | 2121 | static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) |
| 2121 | 2122 | { |
| 2122 | − int max_nch = priv->max_nch; | |
| 2123 | + int max_nch = priv->stats_nch; | |
| 2123 | 2124 | |
| 2124 | 2125 | return (NUM_RQ_STATS * max_nch) + |
| 2125 | 2126 | (NUM_CH_STATS * max_nch) + |
| @@ -2133,7 +2134,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_NUM_STATS(channels) · 7 unmodified lines | ||
| 2133 | 2134 | static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) |
| 2134 | 2135 | { |
| 2135 | 2136 | bool is_xsk = priv->xsk.ever_used; |
| 2136 | − int max_nch = priv->max_nch; | |
| 2137 | + int max_nch = priv->stats_nch; | |
| 2137 | 2138 | int i, j, tc; |
| 2138 | 2139 | |
| 2139 | 2140 | for (i = 0; i < max_nch; i++) |
| @@ -2175,7 +2176,7 @@ static MLX5E_DECLARE_STATS_GRP_OP_FILL_STRS(channels) · 35 unmodified lines | ||
| 2175 | 2176 | static MLX5E_DECLARE_STATS_GRP_OP_FILL_STATS(channels) |
| 2176 | 2177 | { |
| 2177 | 2178 | bool is_xsk = priv->xsk.ever_used; |
| 2178 | − int max_nch = priv->max_nch; | |
| 2179 | + int max_nch = priv->stats_nch; | |
| 2179 | 2180 | int i, j, tc; |
| 2180 | 2181 | |
| 2181 | 2182 | for (i = 0; i < max_nch; i++) |
| @@ -79,12 +79,16 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, · 78 unmodified lines | ||
| 79 | 79 | int dest_num = 0; |
| 80 | 80 | int err = 0; |
| 81 | 81 | |
| 82 | − if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { | |
| 82 | + if (vport->egress.legacy.drop_counter) { | |
| 83 | + drop_counter = vport->egress.legacy.drop_counter; | |
| 84 | + } else if (MLX5_CAP_ESW_EGRESS_ACL(esw->dev, flow_counter)) { | |
| 83 | 85 | drop_counter = mlx5_fc_create(esw->dev, false); |
| 84 | − if (IS_ERR(drop_counter)) | |
| 86 | + if (IS_ERR(drop_counter)) { | |
| 85 | 87 | esw_warn(esw->dev, |
| 86 | 88 | "vport[%d] configure egress drop rule counter err(%ld)\n", |
| 87 | 89 | vport->vport, PTR_ERR(drop_counter)); |
| 90 | + drop_counter = NULL; | |
| 91 | + } | |
| 88 | 92 | vport->egress.legacy.drop_counter = drop_counter; |
| 89 | 93 | } |
| 90 | 94 | |
| @@ -123,7 +127,7 @@ int esw_acl_egress_lgcy_setup(struct mlx5_eswitch *esw, · 32 unmodified lines | ||
| 123 | 127 | flow_act.action = MLX5_FLOW_CONTEXT_ACTION_DROP; |
| 124 | 128 | |
| 125 | 129 | /* Attach egress drop flow counter */ |
| 126 | − if (!IS_ERR_OR_NULL(drop_counter)) { | |
| 130 | + if (drop_counter) { | |
| 127 | 131 | flow_act.action |= MLX5_FLOW_CONTEXT_ACTION_COUNT; |
| 128 | 132 | drop_ctr_dst.type = MLX5_FLOW_DESTINATION_TYPE_COUNTER; |
| 129 | 133 | drop_ctr_dst.counter_id = mlx5_fc_id(drop_counter); |
| @@ -162,7 +166,7 @@ void esw_acl_egress_lgcy_cleanup(struct mlx5_eswitch *esw, · 32 unmodified lines | ||
| 162 | 166 | esw_acl_egress_table_destroy(vport); |
| 163 | 167 | |
| 164 | 168 | clean_drop_counter: |
| 165 | − if (!IS_ERR_OR_NULL(vport->egress.legacy.drop_counter)) { | |
| 169 | + if (vport->egress.legacy.drop_counter) { | |
| 166 | 170 | mlx5_fc_destroy(esw->dev, vport->egress.legacy.drop_counter); |
| 167 | 171 | vport->egress.legacy.drop_counter = NULL; |
| 168 | 172 | } |
| @@ -160,7 +160,9 @@ int esw_acl_ingress_lgcy_setup(struct mlx5_eswitch *esw, · 159 unmodified lines | ||
| 160 | 160 | |
| 161 | 161 | esw_acl_ingress_lgcy_rules_destroy(vport); |
| 162 | 162 | |
| 163 | − if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { | |
| 163 | + if (vport->ingress.legacy.drop_counter) { | |
| 164 | + counter = vport->ingress.legacy.drop_counter; | |
| 165 | + } else if (MLX5_CAP_ESW_INGRESS_ACL(esw->dev, flow_counter)) { | |
| 164 | 166 | counter = mlx5_fc_create(esw->dev, false); |
| 165 | 167 | if (IS_ERR(counter)) { |
| 166 | 168 | esw_warn(esw->dev, |
| @@ -113,7 +113,7 @@ static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv) · 112 unmodified lines | ||
| 113 | 113 | struct mlx5e_sw_stats s = { 0 }; |
| 114 | 114 | int i, j; |
| 115 | 115 | |
| 116 | − for (i = 0; i < priv->max_nch; i++) { | |
| 116 | + for (i = 0; i < priv->stats_nch; i++) { | |
| 117 | 117 | struct mlx5e_channel_stats *channel_stats; |
| 118 | 118 | struct mlx5e_rq_stats *rq_stats; |
| 119 | 119 | |
| @@ -711,7 +711,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u32 port_num, · 591 unmodified lines | ||
| 711 | 711 | goto destroy_ht; |
| 712 | 712 | } |
| 713 | 713 | |
| 714 | − err = mlx5e_priv_init(epriv, netdev, mdev); | |
| 714 | + err = mlx5e_priv_init(epriv, prof, netdev, mdev); | |
| 715 | 715 | if (err) |
| 716 | 716 | goto destroy_mdev_resources; |
| 717 | 717 | |
| @@ -448,22 +448,20 @@ static u64 find_target_cycles(struct mlx5_core_dev *mdev, s64 target_ns) · 447 unmodified lines | ||
| 448 | 448 | return cycles_now + cycles_delta; |
| 449 | 449 | } |
| 450 | 450 | |
| 451 | −static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, | |
| 452 | − s64 sec, u32 nsec) | |
| 451 | +static u64 perout_conf_internal_timer(struct mlx5_core_dev *mdev, s64 sec) | |
| 453 | 452 | { |
| 454 | − struct timespec64 ts; | |
| 453 | + struct timespec64 ts = {}; | |
| 455 | 454 | s64 target_ns; |
| 456 | 455 | |
| 457 | 456 | ts.tv_sec = sec; |
| 458 | − ts.tv_nsec = nsec; | |
| 459 | 457 | target_ns = timespec64_to_ns(&ts); |
| 460 | 458 | |
| 461 | 459 | return find_target_cycles(mdev, target_ns); |
| 462 | 460 | } |
| 463 | 461 | |
| 464 | −static u64 perout_conf_real_time(s64 sec, u32 nsec) | |
| 462 | +static u64 perout_conf_real_time(s64 sec) | |
| 465 | 463 | { |
| 466 | − return (u64)nsec | (u64)sec << 32; | |
| 464 | + return (u64)sec << 32; | |
| 467 | 465 | } |
| 468 | 466 | |
| 469 | 467 | static int mlx5_perout_configure(struct ptp_clock_info *ptp, |
| @@ -474,6 +472,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 4 unmodified lines | ||
| 474 | 472 | container_of(ptp, struct mlx5_clock, ptp_info); |
| 475 | 473 | struct mlx5_core_dev *mdev = |
| 476 | 474 | container_of(clock, struct mlx5_core_dev, clock); |
| 475 | + bool rt_mode = mlx5_real_time_mode(mdev); | |
| 477 | 476 | u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; |
| 478 | 477 | struct timespec64 ts; |
| 479 | 478 | u32 field_select = 0; |
| @@ -501,8 +500,10 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 21 unmodified lines | ||
| 501 | 500 | |
| 502 | 501 | if (on) { |
| 503 | 502 | bool rt_mode = mlx5_real_time_mode(mdev); |
| 504 | − u32 nsec; | |
| 505 | − s64 sec; | |
| 503 | + s64 sec = rq->perout.start.sec; | |
| 504 | + | |
| 505 | + if (rq->perout.start.nsec) | |
| 506 | + return -EINVAL; | |
| 506 | 507 | |
| 507 | 508 | pin_mode = MLX5_PIN_MODE_OUT; |
| 508 | 509 | pattern = MLX5_OUT_PATTERN_PERIODIC; |
| @@ -513,14 +514,11 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 4 unmodified lines | ||
| 513 | 514 | if ((ns >> 1) != 500000000LL) |
| 514 | 515 | return -EINVAL; |
| 515 | 516 | |
| 516 | − nsec = rq->perout.start.nsec; | |
| 517 | − sec = rq->perout.start.sec; | |
| 518 | − | |
| 519 | 517 | if (rt_mode && sec > U32_MAX) |
| 520 | 518 | return -EINVAL; |
| 521 | 519 | |
| 522 | − time_stamp = rt_mode ? perout_conf_real_time(sec, nsec) : | |
| 523 | − perout_conf_internal_timer(mdev, sec, nsec); | |
| 520 | + time_stamp = rt_mode ? perout_conf_real_time(sec) : | |
| 521 | + perout_conf_internal_timer(mdev, sec); | |
| 524 | 522 | |
| 525 | 523 | field_select |= MLX5_MTPPS_FS_PIN_MODE | |
| 526 | 524 | MLX5_MTPPS_FS_PATTERN | |
| @@ -538,6 +536,9 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, · 11 unmodified lines | ||
| 538 | 536 | if (err) |
| 539 | 537 | return err; |
| 540 | 538 | |
| 539 | + if (rt_mode) | |
| 540 | + return 0; | |
| 541 | + | |
| 541 | 542 | return mlx5_set_mtppse(mdev, pin, 0, |
| 542 | 543 | MLX5_EVENT_MODE_REPETETIVE & on); |
| 543 | 544 | } |
| @@ -705,20 +706,14 @@ static void ts_next_sec(struct timespec64 *ts) · 161 unmodified lines | ||
| 705 | 706 | static u64 perout_conf_next_event_timer(struct mlx5_core_dev *mdev, |
| 706 | 707 | struct mlx5_clock *clock) |
| 707 | 708 | { |
| 708 | − bool rt_mode = mlx5_real_time_mode(mdev); | |
| 709 | 709 | struct timespec64 ts; |
| 710 | 710 | s64 target_ns; |
| 711 | 711 | |
| 712 | − if (rt_mode) | |
| 713 | − ts = mlx5_ptp_gettimex_real_time(mdev, NULL); | |
| 714 | − else | |
| 715 | − mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL); | |
| 716 | − | |
| 712 | + mlx5_ptp_gettimex(&clock->ptp_info, &ts, NULL); | |
| 717 | 713 | ts_next_sec(&ts); |
| 718 | 714 | target_ns = timespec64_to_ns(&ts); |
| 719 | 715 | |
| 720 | − return rt_mode ? perout_conf_real_time(ts.tv_sec, ts.tv_nsec) : | |
| 721 | − find_target_cycles(mdev, target_ns); | |
| 716 | + return find_target_cycles(mdev, target_ns); | |
| 722 | 717 | } |
| 723 | 718 | |
| 724 | 719 | static int mlx5_pps_event(struct notifier_block *nb, |
| @@ -13,8 +13,8 @@ · 12 unmodified lines | ||
| 13 | 13 | #endif |
| 14 | 14 | |
| 15 | 15 | #define MLX5_MAX_IRQ_NAME (32) |
| 16 | −/* max irq_index is 255. three chars */ | |
| 17 | −#define MLX5_MAX_IRQ_IDX_CHARS (3) | |
| 16 | +/* max irq_index is 2047, so four chars */ | |
| 17 | +#define MLX5_MAX_IRQ_IDX_CHARS (4) | |
| 18 | 18 | |
| 19 | 19 | #define MLX5_SFS_PER_CTRL_IRQ 64 |
| 20 | 20 | #define MLX5_IRQ_CTRL_SF_MAX 8 |
| @@ -633,8 +633,9 @@ void mlx5_irq_table_destroy(struct mlx5_core_dev *dev) · 612 unmodified lines | ||
| 633 | 633 | int mlx5_irq_table_get_sfs_vec(struct mlx5_irq_table *table) |
| 634 | 634 | { |
| 635 | 635 | if (table->sf_comp_pool) |
| 636 | − return table->sf_comp_pool->xa_num_irqs.max - | |
| 637 | − table->sf_comp_pool->xa_num_irqs.min + 1; | |
| 636 | + return min_t(int, num_online_cpus(), | |
| 637 | + table->sf_comp_pool->xa_num_irqs.max - | |
| 638 | + table->sf_comp_pool->xa_num_irqs.min + 1); | |
| 638 | 639 | else |
| 639 | 640 | return mlx5_irq_table_get_num_comp(table); |
| 640 | 641 | } |
| @@ -998,8 +998,8 @@ ocelot_vcap_block_find_filter_by_index(struct ocelot_vcap_block *block, · 997 unmodified lines | ||
| 998 | 998 | } |
| 999 | 999 | |
| 1000 | 1000 | struct ocelot_vcap_filter * |
| 1001 | −ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int cookie, | |
| 1002 | − bool tc_offload) | |
| 1001 | +ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, | |
| 1002 | + unsigned long cookie, bool tc_offload) | |
| 1003 | 1003 | { |
| 1004 | 1004 | struct ocelot_vcap_filter *filter; |
| 1005 | 1005 | |
| @@ -1292,8 +1292,10 @@ int ionic_lif_addr_add(struct ionic_lif *lif, const u8 *addr) · 1291 unmodified lines | ||
| 1292 | 1292 | if (err && err != -EEXIST) { |
| 1293 | 1293 | /* set the state back to NEW so we can try again later */ |
| 1294 | 1294 | f = ionic_rx_filter_by_addr(lif, addr); |
| 1295 | − if (f && f->state == IONIC_FILTER_STATE_SYNCED) | |
| 1295 | + if (f && f->state == IONIC_FILTER_STATE_SYNCED) { | |
| 1296 | 1296 | f->state = IONIC_FILTER_STATE_NEW; |
| 1297 | + set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state); | |
| 1298 | + } | |
| 1297 | 1299 | |
| 1298 | 1300 | spin_unlock_bh(&lif->rx_filters.lock); |
| 1299 | 1301 | |
| @@ -349,9 +349,6 @@ loop_out: · 348 unmodified lines | ||
| 349 | 349 | list_for_each_entry_safe(sync_item, spos, &sync_add_list, list) { |
| 350 | 350 | (void)ionic_lif_addr_add(lif, sync_item->f.cmd.mac.addr); |
| 351 | 351 | |
| 352 | − if (sync_item->f.state != IONIC_FILTER_STATE_SYNCED) | |
| 353 | − set_bit(IONIC_LIF_F_FILTER_SYNC_NEEDED, lif->state); | |
| 354 | − | |
| 355 | 352 | list_del(&sync_item->list); |
| 356 | 353 | devm_kfree(dev, sync_item); |
| 357 | 354 | } |
| @@ -21,6 +21,7 @@ · 20 unmodified lines | ||
| 21 | 21 | #include <linux/delay.h> |
| 22 | 22 | #include <linux/mfd/syscon.h> |
| 23 | 23 | #include <linux/regmap.h> |
| 24 | +#include <linux/pm_runtime.h> | |
| 24 | 25 | |
| 25 | 26 | #include "stmmac_platform.h" |
| 26 | 27 | |
| @@ -1528,6 +1529,8 @@ static int rk_gmac_powerup(struct rk_priv_data *bsp_priv) · 1501 unmodified lines | ||
| 1528 | 1529 | return ret; |
| 1529 | 1530 | } |
| 1530 | 1531 | |
| 1532 | + pm_runtime_get_sync(dev); | |
| 1533 | + | |
| 1531 | 1534 | if (bsp_priv->integrated_phy) |
| 1532 | 1535 | rk_gmac_integrated_phy_powerup(bsp_priv); |
| 1533 | 1536 | |
| @@ -1539,6 +1542,8 @@ static void rk_gmac_powerdown(struct rk_priv_data *gmac) · 5 unmodified lines | ||
| 1539 | 1542 | if (gmac->integrated_phy) |
| 1540 | 1543 | rk_gmac_integrated_phy_powerdown(gmac); |
| 1541 | 1544 | |
| 1545 | + pm_runtime_put_sync(&gmac->pdev->dev); | |
| 1546 | + | |
| 1542 | 1547 | phy_power_on(gmac, false); |
| 1543 | 1548 | gmac_clk_enable(gmac, false); |
| 1544 | 1549 | } |
| @@ -477,6 +477,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv) · 476 unmodified lines | ||
| 477 | 477 | stmmac_lpi_entry_timer_config(priv, 0); |
| 478 | 478 | del_timer_sync(&priv->eee_ctrl_timer); |
| 479 | 479 | stmmac_set_eee_timer(priv, priv->hw, 0, eee_tw_timer); |
| 480 | + if (priv->hw->xpcs) | |
| 481 | + xpcs_config_eee(priv->hw->xpcs, | |
| 482 | + priv->plat->mult_fact_100ns, | |
| 483 | + false); | |
| 480 | 484 | } |
| 481 | 485 | mutex_unlock(&priv->lock); |
| 482 | 486 | return false; |
| @@ -1038,7 +1042,7 @@ static void stmmac_mac_link_down(struct phylink_config *config, · 555 unmodified lines | ||
| 1038 | 1042 | stmmac_mac_set(priv, priv->ioaddr, false); |
| 1039 | 1043 | priv->eee_active = false; |
| 1040 | 1044 | priv->tx_lpi_enabled = false; |
| 1041 | − stmmac_eee_init(priv); | |
| 1045 | + priv->eee_enabled = stmmac_eee_init(priv); | |
| 1042 | 1046 | stmmac_set_eee_pls(priv, priv->hw, false); |
| 1043 | 1047 | |
| 1044 | 1048 | if (priv->dma_cap.fpesel) |
| @@ -666,6 +666,10 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) · 665 unmodified lines | ||
| 666 | 666 | { |
| 667 | 667 | int ret; |
| 668 | 668 | |
| 669 | + ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); | |
| 670 | + if (ret < 0) | |
| 671 | + return ret; | |
| 672 | + | |
| 669 | 673 | if (enable) { |
| 670 | 674 | /* Enable EEE */ |
| 671 | 675 | ret = DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | |
| @@ -673,9 +677,6 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) · 1 unmodified line | ||
| 673 | 677 | DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | |
| 674 | 678 | mult_fact_100ns << DW_VR_MII_EEE_MULT_FACT_100NS_SHIFT; |
| 675 | 679 | } else { |
| 676 | − ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL0); | |
| 677 | − if (ret < 0) | |
| 678 | − return ret; | |
| 679 | 680 | ret &= ~(DW_VR_MII_EEE_LTX_EN | DW_VR_MII_EEE_LRX_EN | |
| 680 | 681 | DW_VR_MII_EEE_TX_QUIET_EN | DW_VR_MII_EEE_RX_QUIET_EN | |
| 681 | 682 | DW_VR_MII_EEE_TX_EN_CTRL | DW_VR_MII_EEE_RX_EN_CTRL | |
| @@ -690,21 +691,28 @@ int xpcs_config_eee(struct dw_xpcs *xpcs, int mult_fact_100ns, int enable) · 8 unmodified lines | ||
| 690 | 691 | if (ret < 0) |
| 691 | 692 | return ret; |
| 692 | 693 | |
| 693 | − ret |= DW_VR_MII_EEE_TRN_LPI; | |
| 694 | + if (enable) | |
| 695 | + ret |= DW_VR_MII_EEE_TRN_LPI; | |
| 696 | + else | |
| 697 | + ret &= ~DW_VR_MII_EEE_TRN_LPI; | |
| 698 | + | |
| 694 | 699 | return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_EEE_MCTRL1, ret); |
| 695 | 700 | } |
| 696 | 701 | EXPORT_SYMBOL_GPL(xpcs_config_eee); |
| 697 | 702 | |
| 698 | 703 | static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) |
| 699 | 704 | { |
| 700 | − int ret; | |
| 705 | + int ret, mdio_ctrl; | |
| 701 | 706 | |
| 702 | 707 | /* For AN for C37 SGMII mode, the settings are :- |
| 703 | − * 1) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) | |
| 704 | − * 2) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) | |
| 708 | + * 1) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 0b (Disable SGMII AN in case | |
| 709 | + it is already enabled) | |
| 710 | + * 2) VR_MII_AN_CTRL Bit(2:1)[PCS_MODE] = 10b (SGMII AN) | |
| 711 | + * 3) VR_MII_AN_CTRL Bit(3) [TX_CONFIG] = 0b (MAC side SGMII) | |
| 705 | 712 | * DW xPCS used with DW EQoS MAC is always MAC side SGMII. |
| 706 | − * 3) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic | |
| 713 | + * 4) VR_MII_DIG_CTRL1 Bit(9) [MAC_AUTO_SW] = 1b (Automatic | |
| 707 | 714 | * speed/duplex mode change by HW after SGMII AN complete) |
| 715 | + * 5) VR_MII_MMD_CTRL Bit(12) [AN_ENABLE] = 1b (Enable SGMII AN) | |
| 708 | 716 | * |
| 709 | 717 | * Note: Since it is MAC side SGMII, there is no need to set |
| 710 | 718 | * SR_MII_AN_ADV. MAC side SGMII receives AN Tx Config from |
| @@ -712,6 +720,17 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) · 1 unmodified line | ||
| 712 | 720 | * between PHY and Link Partner. There is also no need to |
| 713 | 721 | * trigger AN restart for MAC-side SGMII. |
| 714 | 722 | */ |
| 723 | + mdio_ctrl = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL); | |
| 724 | + if (mdio_ctrl < 0) | |
| 725 | + return mdio_ctrl; | |
| 726 | + | |
| 727 | + if (mdio_ctrl & AN_CL37_EN) { | |
| 728 | + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, | |
| 729 | + mdio_ctrl & ~AN_CL37_EN); | |
| 730 | + if (ret < 0) | |
| 731 | + return ret; | |
| 732 | + } | |
| 733 | + | |
| 715 | 734 | ret = xpcs_read(xpcs, MDIO_MMD_VEND2, DW_VR_MII_AN_CTRL); |
| 716 | 735 | if (ret < 0) |
| 717 | 736 | return ret; |
| @@ -736,7 +755,15 @@ static int xpcs_config_aneg_c37_sgmii(struct dw_xpcs *xpcs, unsigned int mode) · 18 unmodified lines | ||
| 736 | 755 | else |
| 737 | 756 | ret &= ~DW_VR_MII_DIG_CTRL1_MAC_AUTO_SW; |
| 738 | 757 | |
| 739 | − return xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); | |
| 758 | + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_DIG_CTRL1, ret); | |
| 759 | + if (ret < 0) | |
| 760 | + return ret; | |
| 761 | + | |
| 762 | + if (phylink_autoneg_inband(mode)) | |
| 763 | + ret = xpcs_write(xpcs, MDIO_MMD_VEND2, DW_VR_MII_MMD_CTRL, | |
| 764 | + mdio_ctrl | AN_CL37_EN); | |
| 765 | + | |
| 766 | + return ret; | |
| 740 | 767 | } |
| 741 | 768 | |
| 742 | 769 | static int xpcs_config_2500basex(struct dw_xpcs *xpcs) |
| @@ -538,10 +538,16 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) · 537 unmodified lines | ||
| 538 | 538 | bus->dev.groups = NULL; |
| 539 | 539 | dev_set_name(&bus->dev, "%s", bus->id); |
| 540 | 540 | |
| 541 | + /* We need to set state to MDIOBUS_UNREGISTERED to correctly release | |
| 542 | + * the device in mdiobus_free() | |
| 543 | + * | |
| 544 | + * State will be updated later in this function in case of success | |
| 545 | + */ | |
| 546 | + bus->state = MDIOBUS_UNREGISTERED; | |
| 547 | + | |
| 541 | 548 | err = device_register(&bus->dev); |
| 542 | 549 | if (err) { |
| 543 | 550 | pr_err("mii_bus %s failed to register\n", bus->id); |
| 544 | − put_device(&bus->dev); | |
| 545 | 551 | return -EINVAL; |
| 546 | 552 | } |
| 547 | 553 | |
| @@ -134,7 +134,7 @@ static const char * const sm_state_strings[] = { · 133 unmodified lines | ||
| 134 | 134 | [SFP_S_LINK_UP] = "link_up", |
| 135 | 135 | [SFP_S_TX_FAULT] = "tx_fault", |
| 136 | 136 | [SFP_S_REINIT] = "reinit", |
| 137 | − [SFP_S_TX_DISABLE] = "rx_disable", | |
| 137 | + [SFP_S_TX_DISABLE] = "tx_disable", | |
| 138 | 138 | }; |
| 139 | 139 | |
| 140 | 140 | static const char *sm_state_to_str(unsigned short sm_state) |
| @@ -767,6 +767,7 @@ enum rtl8152_flags { · 766 unmodified lines | ||
| 767 | 767 | PHY_RESET, |
| 768 | 768 | SCHEDULE_TASKLET, |
| 769 | 769 | GREEN_ETHERNET, |
| 770 | + RX_EPROTO, | |
| 770 | 771 | }; |
| 771 | 772 | |
| 772 | 773 | #define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2 0x3082 |
| @@ -1770,6 +1771,14 @@ static void read_bulk_callback(struct urb *urb) · 997 unmodified lines | ||
| 1770 | 1771 | rtl_set_unplug(tp); |
| 1771 | 1772 | netif_device_detach(tp->netdev); |
| 1772 | 1773 | return; |
| 1774 | + case -EPROTO: | |
| 1775 | + urb->actual_length = 0; | |
| 1776 | + spin_lock_irqsave(&tp->rx_lock, flags); | |
| 1777 | + list_add_tail(&agg->list, &tp->rx_done); | |
| 1778 | + spin_unlock_irqrestore(&tp->rx_lock, flags); | |
| 1779 | + set_bit(RX_EPROTO, &tp->flags); | |
| 1780 | + schedule_delayed_work(&tp->schedule, 1); | |
| 1781 | + return; | |
| 1773 | 1782 | case -ENOENT: |
| 1774 | 1783 | return; /* the urb is in unlink state */ |
| 1775 | 1784 | case -ETIME: |
| @@ -2425,6 +2434,7 @@ static int rx_bottom(struct r8152 *tp, int budget) · 649 unmodified lines | ||
| 2425 | 2434 | if (list_empty(&tp->rx_done)) |
| 2426 | 2435 | goto out1; |
| 2427 | 2436 | |
| 2437 | + clear_bit(RX_EPROTO, &tp->flags); | |
| 2428 | 2438 | INIT_LIST_HEAD(&rx_queue); |
| 2429 | 2439 | spin_lock_irqsave(&tp->rx_lock, flags); |
| 2430 | 2440 | list_splice_init(&tp->rx_done, &rx_queue); |
| @@ -2441,7 +2451,7 @@ static int rx_bottom(struct r8152 *tp, int budget) · 10 unmodified lines | ||
| 2441 | 2451 | |
| 2442 | 2452 | agg = list_entry(cursor, struct rx_agg, list); |
| 2443 | 2453 | urb = agg->urb; |
| 2444 | − if (urb->actual_length < ETH_ZLEN) | |
| 2454 | + if (urb->status != 0 || urb->actual_length < ETH_ZLEN) | |
| 2445 | 2455 | goto submit; |
| 2446 | 2456 | |
| 2447 | 2457 | agg_free = rtl_get_free_rx(tp, GFP_ATOMIC); |
| @@ -6643,6 +6653,10 @@ static void rtl_work_func_t(struct work_struct *work) · 4195 unmodified lines | ||
| 6643 | 6653 | netif_carrier_ok(tp->netdev)) |
| 6644 | 6654 | tasklet_schedule(&tp->tx_tl); |
| 6645 | 6655 | |
| 6656 | + if (test_and_clear_bit(RX_EPROTO, &tp->flags) && | |
| 6657 | + !list_empty(&tp->rx_done)) | |
| 6658 | + napi_schedule(&tp->napi); | |
| 6659 | + | |
| 6646 | 6660 | mutex_unlock(&tp->control); |
| 6647 | 6661 | |
| 6648 | 6662 | out1: |
| @@ -3,9 +3,7 @@ config ATH5K · 2 unmodified lines | ||
| 3 | 3 | tristate "Atheros 5xxx wireless cards support" |
| 4 | 4 | depends on (PCI || ATH25) && MAC80211 |
| 5 | 5 | select ATH_COMMON |
| 6 | − select MAC80211_LEDS | |
| 7 | − select LEDS_CLASS | |
| 8 | − select NEW_LEDS | |
| 6 | + select MAC80211_LEDS if LEDS_CLASS=y || LEDS_CLASS=MAC80211 | |
| 9 | 7 | select ATH5K_AHB if ATH25 |
| 10 | 8 | select ATH5K_PCI if !ATH25 |
| 11 | 9 | help |
| @@ -89,7 +89,8 @@ static const struct pci_device_id ath5k_led_devices[] = { · 88 unmodified lines | ||
| 89 | 89 | |
| 90 | 90 | void ath5k_led_enable(struct ath5k_hw *ah) |
| 91 | 91 | { |
| 92 | − if (test_bit(ATH_STAT_LEDSOFT, ah->status)) { | |
| 92 | + if (IS_ENABLED(CONFIG_MAC80211_LEDS) && | |
| 93 | + test_bit(ATH_STAT_LEDSOFT, ah->status)) { | |
| 93 | 94 | ath5k_hw_set_gpio_output(ah, ah->led_pin); |
| 94 | 95 | ath5k_led_off(ah); |
| 95 | 96 | } |
| @@ -104,7 +105,8 @@ static void ath5k_led_on(struct ath5k_hw *ah) · 8 unmodified lines | ||
| 104 | 105 | |
| 105 | 106 | void ath5k_led_off(struct ath5k_hw *ah) |
| 106 | 107 | { |
| 107 | − if (!test_bit(ATH_STAT_LEDSOFT, ah->status)) | |
| 108 | + if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || | |
| 109 | + !test_bit(ATH_STAT_LEDSOFT, ah->status)) | |
| 108 | 110 | return; |
| 109 | 111 | ath5k_hw_set_gpio(ah, ah->led_pin, !ah->led_on); |
| 110 | 112 | } |
| @@ -146,7 +148,7 @@ ath5k_register_led(struct ath5k_hw *ah, struct ath5k_led *led, · 35 unmodified lines | ||
| 146 | 148 | static void |
| 147 | 149 | ath5k_unregister_led(struct ath5k_led *led) |
| 148 | 150 | { |
| 149 | − if (!led->ah) | |
| 151 | + if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !led->ah) | |
| 150 | 152 | return; |
| 151 | 153 | led_classdev_unregister(&led->led_dev); |
| 152 | 154 | ath5k_led_off(led->ah); |
| @@ -169,7 +171,7 @@ int ath5k_init_leds(struct ath5k_hw *ah) · 16 unmodified lines | ||
| 169 | 171 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; |
| 170 | 172 | const struct pci_device_id *match; |
| 171 | 173 | |
| 172 | − if (!ah->pdev) | |
| 174 | + if (!IS_ENABLED(CONFIG_MAC80211_LEDS) || !ah->pdev) | |
| 173 | 175 | return 0; |
| 174 | 176 | |
| 175 | 177 | #ifdef CONFIG_ATH5K_AHB |
| @@ -7463,23 +7463,18 @@ static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2], · 7462 unmodified lines | ||
| 7463 | 7463 | s32 found_index; |
| 7464 | 7464 | int i; |
| 7465 | 7465 | |
| 7466 | + country_codes = drvr->settings->country_codes; | |
| 7467 | + if (!country_codes) { | |
| 7468 | + brcmf_dbg(TRACE, "No country codes configured for device\n"); | |
| 7469 | + return -EINVAL; | |
| 7470 | + } | |
| 7471 | + | |
| 7466 | 7472 | if ((alpha2[0] == ccreq->country_abbrev[0]) && |
| 7467 | 7473 | (alpha2[1] == ccreq->country_abbrev[1])) { |
| 7468 | 7474 | brcmf_dbg(TRACE, "Country code already set\n"); |
| 7469 | 7475 | return -EAGAIN; |
| 7470 | 7476 | } |
| 7471 | 7477 | |
| 7472 | − country_codes = drvr->settings->country_codes; | |
| 7473 | − if (!country_codes) { | |
| 7474 | − brcmf_dbg(TRACE, "No country codes configured for device, using ISO3166 code and 0 rev\n"); | |
| 7475 | − memset(ccreq, 0, sizeof(*ccreq)); | |
| 7476 | − ccreq->country_abbrev[0] = alpha2[0]; | |
| 7477 | − ccreq->country_abbrev[1] = alpha2[1]; | |
| 7478 | − ccreq->ccode[0] = alpha2[0]; | |
| 7479 | − ccreq->ccode[1] = alpha2[1]; | |
| 7480 | − return 0; | |
| 7481 | − } | |
| 7482 | − | |
| 7483 | 7478 | found_index = -1; |
| 7484 | 7479 | for (i = 0; i < country_codes->table_size; i++) { |
| 7485 | 7480 | cc = &country_codes->table[i]; |
| @@ -160,6 +160,7 @@ static void iwl_mvm_wowlan_program_keys(struct ieee80211_hw *hw, · 159 unmodified lines | ||
| 160 | 160 | mvm->ptk_icvlen = key->icv_len; |
| 161 | 161 | mvm->gtk_ivlen = key->iv_len; |
| 162 | 162 | mvm->gtk_icvlen = key->icv_len; |
| 163 | + mutex_unlock(&mvm->mutex); | |
| 163 | 164 | |
| 164 | 165 | /* don't upload key again */ |
| 165 | 166 | return; |
| @@ -360,11 +361,11 @@ static void iwl_mvm_wowlan_get_rsc_v5_data(struct ieee80211_hw *hw, · 194 unmodified lines | ||
| 360 | 361 | if (sta) { |
| 361 | 362 | rsc = data->rsc->ucast_rsc; |
| 362 | 363 | } else { |
| 363 | − if (WARN_ON(data->gtks > ARRAY_SIZE(data->gtk_ids))) | |
| 364 | + if (WARN_ON(data->gtks >= ARRAY_SIZE(data->gtk_ids))) | |
| 364 | 365 | return; |
| 365 | 366 | data->gtk_ids[data->gtks] = key->keyidx; |
| 366 | 367 | rsc = data->rsc->mcast_rsc[data->gtks % 2]; |
| 367 | − if (WARN_ON(key->keyidx > | |
| 368 | + if (WARN_ON(key->keyidx >= | |
| 368 | 369 | ARRAY_SIZE(data->rsc->mcast_key_id_map))) |
| 369 | 370 | return; |
| 370 | 371 | data->rsc->mcast_key_id_map[key->keyidx] = data->gtks % 2; |
| @@ -662,12 +662,13 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, · 661 unmodified lines | ||
| 662 | 662 | u32 *uid) |
| 663 | 663 | { |
| 664 | 664 | u32 id; |
| 665 | − struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | |
| 665 | + struct iwl_mvm_vif *mvmvif; | |
| 666 | 666 | enum nl80211_iftype iftype; |
| 667 | 667 | |
| 668 | 668 | if (!te_data->vif) |
| 669 | 669 | return false; |
| 670 | 670 | |
| 671 | + mvmvif = iwl_mvm_vif_from_mac80211(te_data->vif); | |
| 671 | 672 | iftype = te_data->vif->type; |
| 672 | 673 | |
| 673 | 674 | /* |
| @@ -547,6 +547,8 @@ static const struct iwl_dev_info iwl_dev_info_table[] = { · 546 unmodified lines | ||
| 547 | 547 | IWL_DEV_INFO(0x43F0, 0x0074, iwl_ax201_cfg_qu_hr, NULL), |
| 548 | 548 | IWL_DEV_INFO(0x43F0, 0x0078, iwl_ax201_cfg_qu_hr, NULL), |
| 549 | 549 | IWL_DEV_INFO(0x43F0, 0x007C, iwl_ax201_cfg_qu_hr, NULL), |
| 550 | + IWL_DEV_INFO(0x43F0, 0x1651, killer1650s_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650s_name), | |
| 551 | + IWL_DEV_INFO(0x43F0, 0x1652, killer1650i_2ax_cfg_qu_b0_hr_b0, iwl_ax201_killer_1650i_name), | |
| 550 | 552 | IWL_DEV_INFO(0x43F0, 0x2074, iwl_ax201_cfg_qu_hr, NULL), |
| 551 | 553 | IWL_DEV_INFO(0x43F0, 0x4070, iwl_ax201_cfg_qu_hr, NULL), |
| 552 | 554 | IWL_DEV_INFO(0xA0F0, 0x0070, iwl_ax201_cfg_qu_hr, NULL), |
| @@ -62,8 +62,8 @@ void *mwifiex_process_sta_txpd(struct mwifiex_private *priv, · 61 unmodified lines | ||
| 62 | 62 | |
| 63 | 63 | pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0; |
| 64 | 64 | |
| 65 | − pad = ((void *)skb->data - (sizeof(*local_tx_pd) + hroom)- | |
| 66 | − NULL) & (MWIFIEX_DMA_ALIGN_SZ - 1); | |
| 65 | + pad = ((uintptr_t)skb->data - (sizeof(*local_tx_pd) + hroom)) & | |
| 66 | + (MWIFIEX_DMA_ALIGN_SZ - 1); | |
| 67 | 67 | skb_push(skb, sizeof(*local_tx_pd) + pad); |
| 68 | 68 | |
| 69 | 69 | local_tx_pd = (struct txpd *) skb->data; |
| @@ -475,8 +475,8 @@ void *mwifiex_process_uap_txpd(struct mwifiex_private *priv, · 474 unmodified lines | ||
| 475 | 475 | |
| 476 | 476 | pkt_type = mwifiex_is_skb_mgmt_frame(skb) ? PKT_TYPE_MGMT : 0; |
| 477 | 477 | |
| 478 | − pad = ((void *)skb->data - (sizeof(*txpd) + hroom) - NULL) & | |
| 479 | − (MWIFIEX_DMA_ALIGN_SZ - 1); | |
| 478 | + pad = ((uintptr_t)skb->data - (sizeof(*txpd) + hroom)) & | |
| 479 | + (MWIFIEX_DMA_ALIGN_SZ - 1); | |
| 480 | 480 | |
| 481 | 481 | skb_push(skb, sizeof(*txpd) + pad); |
| 482 | 482 | |
| @@ -644,6 +644,7 @@ static const struct pci_device_id pch_ieee1588_pcidev_id[] = { · 643 unmodified lines | ||
| 644 | 644 | }, |
| 645 | 645 | {0} |
| 646 | 646 | }; |
| 647 | +MODULE_DEVICE_TABLE(pci, pch_ieee1588_pcidev_id); | |
| 647 | 648 | |
| 648 | 649 | static SIMPLE_DEV_PM_OPS(pch_pm_ops, pch_suspend, pch_resume); |
| 649 | 650 | |
| @@ -308,7 +308,7 @@ static inline void ether_addr_copy(u8 *dst, const u8 *src) · 307 unmodified lines | ||
| 308 | 308 | */ |
| 309 | 309 | static inline void eth_hw_addr_set(struct net_device *dev, const u8 *addr) |
| 310 | 310 | { |
| 311 | − ether_addr_copy(dev->dev_addr, addr); | |
| 311 | + __dev_addr_set(dev, addr, ETH_ALEN); | |
| 312 | 312 | } |
| 313 | 313 | |
| 314 | 314 | /** |
| @@ -17,7 +17,6 @@ struct inet_frags_ctl; · 16 unmodified lines | ||
| 17 | 17 | struct nft_ct_frag6_pernet { |
| 18 | 18 | struct ctl_table_header *nf_frag_frags_hdr; |
| 19 | 19 | struct fqdir *fqdir; |
| 20 | − unsigned int users; | |
| 21 | 20 | }; |
| 22 | 21 | |
| 23 | 22 | #endif /* _NF_DEFRAG_IPV6_H */ |
| @@ -1202,7 +1202,7 @@ struct nft_object *nft_obj_lookup(const struct net *net, · 1201 unmodified lines | ||
| 1202 | 1202 | |
| 1203 | 1203 | void nft_obj_notify(struct net *net, const struct nft_table *table, |
| 1204 | 1204 | struct nft_object *obj, u32 portid, u32 seq, |
| 1205 | − int event, int family, int report, gfp_t gfp); | |
| 1205 | + int event, u16 flags, int family, int report, gfp_t gfp); | |
| 1206 | 1206 | |
| 1207 | 1207 | /** |
| 1208 | 1208 | * struct nft_object_type - stateful object type |
| @@ -27,5 +27,11 @@ struct netns_nf { · 26 unmodified lines | ||
| 27 | 27 | #if IS_ENABLED(CONFIG_DECNET) |
| 28 | 28 | struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS]; |
| 29 | 29 | #endif |
| 30 | +#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4) | |
| 31 | + unsigned int defrag_ipv4_users; | |
| 32 | +#endif | |
| 33 | +#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) | |
| 34 | + unsigned int defrag_ipv6_users; | |
| 35 | +#endif | |
| 30 | 36 | }; |
| 31 | 37 | #endif |
| @@ -307,6 +307,7 @@ struct bpf_local_storage; · 306 unmodified lines | ||
| 307 | 307 | * @sk_priority: %SO_PRIORITY setting |
| 308 | 308 | * @sk_type: socket type (%SOCK_STREAM, etc) |
| 309 | 309 | * @sk_protocol: which protocol this socket belongs in this network family |
| 310 | + * @sk_peer_lock: lock protecting @sk_peer_pid and @sk_peer_cred | |
| 310 | 311 | * @sk_peer_pid: &struct pid for this socket's peer |
| 311 | 312 | * @sk_peer_cred: %SO_PEERCRED setting |
| 312 | 313 | * @sk_rcvlowat: %SO_RCVLOWAT setting |
| @@ -694,7 +694,7 @@ int ocelot_vcap_filter_add(struct ocelot *ocelot, · 693 unmodified lines | ||
| 694 | 694 | int ocelot_vcap_filter_del(struct ocelot *ocelot, |
| 695 | 695 | struct ocelot_vcap_filter *rule); |
| 696 | 696 | struct ocelot_vcap_filter * |
| 697 | −ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, int id, | |
| 698 | − bool tc_offload); | |
| 697 | +ocelot_vcap_block_find_filter_by_id(struct ocelot_vcap_block *block, | |
| 698 | + unsigned long cookie, bool tc_offload); | |
| 699 | 699 | |
| 700 | 700 | #endif /* _OCELOT_VCAP_H_ */ |
| @@ -213,13 +213,13 @@ enum { · 212 unmodified lines | ||
| 213 | 213 | XFRM_MSG_GETSPDINFO, |
| 214 | 214 | #define XFRM_MSG_GETSPDINFO XFRM_MSG_GETSPDINFO |
| 215 | 215 | |
| 216 | + XFRM_MSG_MAPPING, | |
| 217 | +#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING | |
| 218 | + | |
| 216 | 219 | XFRM_MSG_SETDEFAULT, |
| 217 | 220 | #define XFRM_MSG_SETDEFAULT XFRM_MSG_SETDEFAULT |
| 218 | 221 | XFRM_MSG_GETDEFAULT, |
| 219 | 222 | #define XFRM_MSG_GETDEFAULT XFRM_MSG_GETDEFAULT |
| 220 | − | |
| 221 | − XFRM_MSG_MAPPING, | |
| 222 | −#define XFRM_MSG_MAPPING XFRM_MSG_MAPPING | |
| 223 | 223 | __XFRM_MSG_MAX |
| 224 | 224 | }; |
| 225 | 225 | #define XFRM_MSG_MAX (__XFRM_MSG_MAX - 1) |
| @@ -514,9 +514,12 @@ struct xfrm_user_offload { · 288 unmodified lines | ||
| 514 | 514 | #define XFRM_OFFLOAD_INBOUND 2 |
| 515 | 515 | |
| 516 | 516 | struct xfrm_userpolicy_default { |
| 517 | −#define XFRM_USERPOLICY_DIRMASK_MAX (sizeof(__u8) * 8) | |
| 518 | − __u8 dirmask; | |
| 519 | − __u8 action; | |
| 517 | +#define XFRM_USERPOLICY_UNSPEC 0 | |
| 518 | +#define XFRM_USERPOLICY_BLOCK 1 | |
| 519 | +#define XFRM_USERPOLICY_ACCEPT 2 | |
| 520 | + __u8 in; | |
| 521 | + __u8 fwd; | |
| 522 | + __u8 out; | |
| 520 | 523 | }; |
| 521 | 524 | |
| 522 | 525 | #ifndef __KERNEL__ |
| @@ -63,7 +63,8 @@ static inline int stack_map_data_size(struct bpf_map *map) · 62 unmodified lines | ||
| 63 | 63 | |
| 64 | 64 | static int prealloc_elems_and_freelist(struct bpf_stack_map *smap) |
| 65 | 65 | { |
| 66 | − u32 elem_size = sizeof(struct stack_map_bucket) + smap->map.value_size; | |
| 66 | + u64 elem_size = sizeof(struct stack_map_bucket) + | |
| 67 | + (u64)smap->map.value_size; | |
| 67 | 68 | int err; |
| 68 | 69 | |
| 69 | 70 | smap->elems = bpf_map_area_alloc(elem_size * smap->map.max_entries, |
| @@ -1666,7 +1666,8 @@ static size_t br_get_linkxstats_size(const struct net_device *dev, int attr) · 1665 unmodified lines | ||
| 1666 | 1666 | } |
| 1667 | 1667 | |
| 1668 | 1668 | return numvls * nla_total_size(sizeof(struct bridge_vlan_xstats)) + |
| 1669 | − nla_total_size(sizeof(struct br_mcast_stats)) + | |
| 1669 | + nla_total_size_64bit(sizeof(struct br_mcast_stats)) + | |
| 1670 | + (p ? nla_total_size_64bit(sizeof(p->stp_xstats)) : 0) + | |
| 1670 | 1671 | nla_total_size(0); |
| 1671 | 1672 | } |
| 1672 | 1673 | |
| @@ -5262,7 +5262,7 @@ nla_put_failure: · 5261 unmodified lines | ||
| 5262 | 5262 | static size_t if_nlmsg_stats_size(const struct net_device *dev, |
| 5263 | 5263 | u32 filter_mask) |
| 5264 | 5264 | { |
| 5265 | − size_t size = 0; | |
| 5265 | + size_t size = NLMSG_ALIGN(sizeof(struct if_stats_msg)); | |
| 5266 | 5266 | |
| 5267 | 5267 | if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_64, 0)) |
| 5268 | 5268 | size += nla_total_size_64bit(sizeof(struct rtnl_link_stats64)); |
| @@ -210,7 +210,7 @@ static struct sk_buff *dsa_rcv_ll(struct sk_buff *skb, struct net_device *dev, · 209 unmodified lines | ||
| 210 | 210 | cmd = dsa_header[0] >> 6; |
| 211 | 211 | switch (cmd) { |
| 212 | 212 | case DSA_CMD_FORWARD: |
| 213 | − trunk = !!(dsa_header[1] & 7); | |
| 213 | + trunk = !!(dsa_header[1] & 4); | |
| 214 | 214 | break; |
| 215 | 215 | |
| 216 | 216 | case DSA_CMD_TO_CPU: |
| @@ -242,8 +242,10 @@ static inline int compute_score(struct sock *sk, struct net *net, · 241 unmodified lines | ||
| 242 | 242 | |
| 243 | 243 | if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) |
| 244 | 244 | return -1; |
| 245 | + score = sk->sk_bound_dev_if ? 2 : 1; | |
| 245 | 246 | |
| 246 | − score = sk->sk_family == PF_INET ? 2 : 1; | |
| 247 | + if (sk->sk_family == PF_INET) | |
| 248 | + score++; | |
| 247 | 249 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
| 248 | 250 | score++; |
| 249 | 251 | } |
| @@ -20,13 +20,8 @@ · 19 unmodified lines | ||
| 20 | 20 | #endif |
| 21 | 21 | #include <net/netfilter/nf_conntrack_zones.h> |
| 22 | 22 | |
| 23 | −static unsigned int defrag4_pernet_id __read_mostly; | |
| 24 | 23 | static DEFINE_MUTEX(defrag4_mutex); |
| 25 | 24 | |
| 26 | −struct defrag4_pernet { | |
| 27 | − unsigned int users; | |
| 28 | −}; | |
| 29 | − | |
| 30 | 25 | static int nf_ct_ipv4_gather_frags(struct net *net, struct sk_buff *skb, |
| 31 | 26 | u_int32_t user) |
| 32 | 27 | { |
| @@ -111,19 +106,15 @@ static const struct nf_hook_ops ipv4_defrag_ops[] = { · 78 unmodified lines | ||
| 111 | 106 | |
| 112 | 107 | static void __net_exit defrag4_net_exit(struct net *net) |
| 113 | 108 | { |
| 114 | − struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); | |
| 115 | − | |
| 116 | − if (nf_defrag->users) { | |
| 109 | + if (net->nf.defrag_ipv4_users) { | |
| 117 | 110 | nf_unregister_net_hooks(net, ipv4_defrag_ops, |
| 118 | 111 | ARRAY_SIZE(ipv4_defrag_ops)); |
| 119 | − nf_defrag->users = 0; | |
| 112 | + net->nf.defrag_ipv4_users = 0; | |
| 120 | 113 | } |
| 121 | 114 | } |
| 122 | 115 | |
| 123 | 116 | static struct pernet_operations defrag4_net_ops = { |
| 124 | 117 | .exit = defrag4_net_exit, |
| 125 | − .id = &defrag4_pernet_id, | |
| 126 | − .size = sizeof(struct defrag4_pernet), | |
| 127 | 118 | }; |
| 128 | 119 | |
| 129 | 120 | static int __init nf_defrag_init(void) |
| @@ -138,24 +129,23 @@ static void __exit nf_defrag_fini(void) · 8 unmodified lines | ||
| 138 | 129 | |
| 139 | 130 | int nf_defrag_ipv4_enable(struct net *net) |
| 140 | 131 | { |
| 141 | − struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); | |
| 142 | 132 | int err = 0; |
| 143 | 133 | |
| 144 | 134 | mutex_lock(&defrag4_mutex); |
| 145 | − if (nf_defrag->users == UINT_MAX) { | |
| 135 | + if (net->nf.defrag_ipv4_users == UINT_MAX) { | |
| 146 | 136 | err = -EOVERFLOW; |
| 147 | 137 | goto out_unlock; |
| 148 | 138 | } |
| 149 | 139 | |
| 150 | − if (nf_defrag->users) { | |
| 151 | − nf_defrag->users++; | |
| 140 | + if (net->nf.defrag_ipv4_users) { | |
| 141 | + net->nf.defrag_ipv4_users++; | |
| 152 | 142 | goto out_unlock; |
| 153 | 143 | } |
| 154 | 144 | |
| 155 | 145 | err = nf_register_net_hooks(net, ipv4_defrag_ops, |
| 156 | 146 | ARRAY_SIZE(ipv4_defrag_ops)); |
| 157 | 147 | if (err == 0) |
| 158 | − nf_defrag->users = 1; | |
| 148 | + net->nf.defrag_ipv4_users = 1; | |
| 159 | 149 | |
| 160 | 150 | out_unlock: |
| 161 | 151 | mutex_unlock(&defrag4_mutex); |
| @@ -165,12 +155,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv4_enable); · 3 unmodified lines | ||
| 165 | 155 | |
| 166 | 156 | void nf_defrag_ipv4_disable(struct net *net) |
| 167 | 157 | { |
| 168 | − struct defrag4_pernet *nf_defrag = net_generic(net, defrag4_pernet_id); | |
| 169 | − | |
| 170 | 158 | mutex_lock(&defrag4_mutex); |
| 171 | − if (nf_defrag->users) { | |
| 172 | − nf_defrag->users--; | |
| 173 | − if (nf_defrag->users == 0) | |
| 159 | + if (net->nf.defrag_ipv4_users) { | |
| 160 | + net->nf.defrag_ipv4_users--; | |
| 161 | + if (net->nf.defrag_ipv4_users == 0) | |
| 174 | 162 | nf_unregister_net_hooks(net, ipv4_defrag_ops, |
| 175 | 163 | ARRAY_SIZE(ipv4_defrag_ops)); |
| 176 | 164 | } |
| @@ -390,7 +390,8 @@ static int compute_score(struct sock *sk, struct net *net, · 389 unmodified lines | ||
| 390 | 390 | dif, sdif); |
| 391 | 391 | if (!dev_match) |
| 392 | 392 | return -1; |
| 393 | − score += 4; | |
| 393 | + if (sk->sk_bound_dev_if) | |
| 394 | + score += 4; | |
| 394 | 395 | |
| 395 | 396 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
| 396 | 397 | score++; |
| @@ -106,7 +106,7 @@ static inline int compute_score(struct sock *sk, struct net *net, · 105 unmodified lines | ||
| 106 | 106 | if (!inet_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif)) |
| 107 | 107 | return -1; |
| 108 | 108 | |
| 109 | − score = 1; | |
| 109 | + score = sk->sk_bound_dev_if ? 2 : 1; | |
| 110 | 110 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
| 111 | 111 | score++; |
| 112 | 112 | } |
| @@ -33,7 +33,7 @@ · 32 unmodified lines | ||
| 33 | 33 | |
| 34 | 34 | static const char nf_frags_cache_name[] = "nf-frags"; |
| 35 | 35 | |
| 36 | −unsigned int nf_frag_pernet_id __read_mostly; | |
| 36 | +static unsigned int nf_frag_pernet_id __read_mostly; | |
| 37 | 37 | static struct inet_frags nf_frags; |
| 38 | 38 | |
| 39 | 39 | static struct nft_ct_frag6_pernet *nf_frag_pernet(struct net *net) |
| @@ -25,8 +25,6 @@ · 24 unmodified lines | ||
| 25 | 25 | #include <net/netfilter/nf_conntrack_zones.h> |
| 26 | 26 | #include <net/netfilter/ipv6/nf_defrag_ipv6.h> |
| 27 | 27 | |
| 28 | −extern unsigned int nf_frag_pernet_id; | |
| 29 | − | |
| 30 | 28 | static DEFINE_MUTEX(defrag6_mutex); |
| 31 | 29 | |
| 32 | 30 | static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum, |
| @@ -91,12 +89,10 @@ static const struct nf_hook_ops ipv6_defrag_ops[] = { · 58 unmodified lines | ||
| 91 | 89 | |
| 92 | 90 | static void __net_exit defrag6_net_exit(struct net *net) |
| 93 | 91 | { |
| 94 | − struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); | |
| 95 | − | |
| 96 | − if (nf_frag->users) { | |
| 92 | + if (net->nf.defrag_ipv6_users) { | |
| 97 | 93 | nf_unregister_net_hooks(net, ipv6_defrag_ops, |
| 98 | 94 | ARRAY_SIZE(ipv6_defrag_ops)); |
| 99 | − nf_frag->users = 0; | |
| 95 | + net->nf.defrag_ipv6_users = 0; | |
| 100 | 96 | } |
| 101 | 97 | } |
| 102 | 98 | |
| @@ -134,24 +130,23 @@ static void __exit nf_defrag_fini(void) · 31 unmodified lines | ||
| 134 | 130 | |
| 135 | 131 | int nf_defrag_ipv6_enable(struct net *net) |
| 136 | 132 | { |
| 137 | − struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); | |
| 138 | 133 | int err = 0; |
| 139 | 134 | |
| 140 | 135 | mutex_lock(&defrag6_mutex); |
| 141 | − if (nf_frag->users == UINT_MAX) { | |
| 136 | + if (net->nf.defrag_ipv6_users == UINT_MAX) { | |
| 142 | 137 | err = -EOVERFLOW; |
| 143 | 138 | goto out_unlock; |
| 144 | 139 | } |
| 145 | 140 | |
| 146 | − if (nf_frag->users) { | |
| 147 | − nf_frag->users++; | |
| 141 | + if (net->nf.defrag_ipv6_users) { | |
| 142 | + net->nf.defrag_ipv6_users++; | |
| 148 | 143 | goto out_unlock; |
| 149 | 144 | } |
| 150 | 145 | |
| 151 | 146 | err = nf_register_net_hooks(net, ipv6_defrag_ops, |
| 152 | 147 | ARRAY_SIZE(ipv6_defrag_ops)); |
| 153 | 148 | if (err == 0) |
| 154 | − nf_frag->users = 1; | |
| 149 | + net->nf.defrag_ipv6_users = 1; | |
| 155 | 150 | |
| 156 | 151 | out_unlock: |
| 157 | 152 | mutex_unlock(&defrag6_mutex); |
| @@ -161,12 +156,10 @@ EXPORT_SYMBOL_GPL(nf_defrag_ipv6_enable); · 3 unmodified lines | ||
| 161 | 156 | |
| 162 | 157 | void nf_defrag_ipv6_disable(struct net *net) |
| 163 | 158 | { |
| 164 | − struct nft_ct_frag6_pernet *nf_frag = net_generic(net, nf_frag_pernet_id); | |
| 165 | − | |
| 166 | 159 | mutex_lock(&defrag6_mutex); |
| 167 | − if (nf_frag->users) { | |
| 168 | − nf_frag->users--; | |
| 169 | − if (nf_frag->users == 0) | |
| 160 | + if (net->nf.defrag_ipv6_users) { | |
| 161 | + net->nf.defrag_ipv6_users--; | |
| 162 | + if (net->nf.defrag_ipv6_users == 0) | |
| 170 | 163 | nf_unregister_net_hooks(net, ipv6_defrag_ops, |
| 171 | 164 | ARRAY_SIZE(ipv6_defrag_ops)); |
| 172 | 165 | } |
| @@ -133,7 +133,8 @@ static int compute_score(struct sock *sk, struct net *net, · 132 unmodified lines | ||
| 133 | 133 | dev_match = udp_sk_bound_dev_eq(net, sk->sk_bound_dev_if, dif, sdif); |
| 134 | 134 | if (!dev_match) |
| 135 | 135 | return -1; |
| 136 | − score++; | |
| 136 | + if (sk->sk_bound_dev_if) | |
| 137 | + score++; | |
| 137 | 138 | |
| 138 | 139 | if (READ_ONCE(sk->sk_incoming_cpu) == raw_smp_processor_id()) |
| 139 | 140 | score++; |
| @@ -780,6 +780,7 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event) · 779 unmodified lines | ||
| 780 | 780 | { |
| 781 | 781 | struct nftables_pernet *nft_net; |
| 782 | 782 | struct sk_buff *skb; |
| 783 | + u16 flags = 0; | |
| 783 | 784 | int err; |
| 784 | 785 | |
| 785 | 786 | if (!ctx->report && |
| @@ -790,8 +791,11 @@ static void nf_tables_table_notify(const struct nft_ctx *ctx, int event) · 4 unmodified lines | ||
| 790 | 791 | if (skb == NULL) |
| 791 | 792 | goto err; |
| 792 | 793 | |
| 794 | + if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | |
| 795 | + flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | |
| 796 | + | |
| 793 | 797 | err = nf_tables_fill_table_info(skb, ctx->net, ctx->portid, ctx->seq, |
| 794 | − event, 0, ctx->family, ctx->table); | |
| 798 | + event, flags, ctx->family, ctx->table); | |
| 795 | 799 | if (err < 0) { |
| 796 | 800 | kfree_skb(skb); |
| 797 | 801 | goto err; |
| @@ -1563,6 +1567,7 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event) · 765 unmodified lines | ||
| 1563 | 1567 | { |
| 1564 | 1568 | struct nftables_pernet *nft_net; |
| 1565 | 1569 | struct sk_buff *skb; |
| 1570 | + u16 flags = 0; | |
| 1566 | 1571 | int err; |
| 1567 | 1572 | |
| 1568 | 1573 | if (!ctx->report && |
| @@ -1573,8 +1578,11 @@ static void nf_tables_chain_notify(const struct nft_ctx *ctx, int event) · 4 unmodified lines | ||
| 1573 | 1578 | if (skb == NULL) |
| 1574 | 1579 | goto err; |
| 1575 | 1580 | |
| 1581 | + if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | |
| 1582 | + flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | |
| 1583 | + | |
| 1576 | 1584 | err = nf_tables_fill_chain_info(skb, ctx->net, ctx->portid, ctx->seq, |
| 1577 | − event, 0, ctx->family, ctx->table, | |
| 1585 | + event, flags, ctx->family, ctx->table, | |
| 1578 | 1586 | ctx->chain); |
| 1579 | 1587 | if (err < 0) { |
| 1580 | 1588 | kfree_skb(skb); |
| @@ -2866,8 +2874,7 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, · 1285 unmodified lines | ||
| 2866 | 2874 | u32 flags, int family, |
| 2867 | 2875 | const struct nft_table *table, |
| 2868 | 2876 | const struct nft_chain *chain, |
| 2869 | − const struct nft_rule *rule, | |
| 2870 | − const struct nft_rule *prule) | |
| 2877 | + const struct nft_rule *rule, u64 handle) | |
| 2871 | 2878 | { |
| 2872 | 2879 | struct nlmsghdr *nlh; |
| 2873 | 2880 | const struct nft_expr *expr, *next; |
| @@ -2887,9 +2894,8 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, · 13 unmodified lines | ||
| 2887 | 2894 | NFTA_RULE_PAD)) |
| 2888 | 2895 | goto nla_put_failure; |
| 2889 | 2896 | |
| 2890 | − if (event != NFT_MSG_DELRULE && prule) { | |
| 2891 | − if (nla_put_be64(skb, NFTA_RULE_POSITION, | |
| 2892 | − cpu_to_be64(prule->handle), | |
| 2897 | + if (event != NFT_MSG_DELRULE && handle) { | |
| 2898 | + if (nla_put_be64(skb, NFTA_RULE_POSITION, cpu_to_be64(handle), | |
| 2893 | 2899 | NFTA_RULE_PAD)) |
| 2894 | 2900 | goto nla_put_failure; |
| 2895 | 2901 | } |
| @@ -2925,7 +2931,10 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, · 29 unmodified lines | ||
| 2925 | 2931 | const struct nft_rule *rule, int event) |
| 2926 | 2932 | { |
| 2927 | 2933 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
| 2934 | + const struct nft_rule *prule; | |
| 2928 | 2935 | struct sk_buff *skb; |
| 2936 | + u64 handle = 0; | |
| 2937 | + u16 flags = 0; | |
| 2929 | 2938 | int err; |
| 2930 | 2939 | |
| 2931 | 2940 | if (!ctx->report && |
| @@ -2936,9 +2945,20 @@ static void nf_tables_rule_notify(const struct nft_ctx *ctx, · 4 unmodified lines | ||
| 2936 | 2945 | if (skb == NULL) |
| 2937 | 2946 | goto err; |
| 2938 | 2947 | |
| 2948 | + if (event == NFT_MSG_NEWRULE && | |
| 2949 | + !list_is_first(&rule->list, &ctx->chain->rules) && | |
| 2950 | + !list_is_last(&rule->list, &ctx->chain->rules)) { | |
| 2951 | + prule = list_prev_entry(rule, list); | |
| 2952 | + handle = prule->handle; | |
| 2953 | + } | |
| 2954 | + if (ctx->flags & (NLM_F_APPEND | NLM_F_REPLACE)) | |
| 2955 | + flags |= NLM_F_APPEND; | |
| 2956 | + if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | |
| 2957 | + flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | |
| 2958 | + | |
| 2939 | 2959 | err = nf_tables_fill_rule_info(skb, ctx->net, ctx->portid, ctx->seq, |
| 2940 | − event, 0, ctx->family, ctx->table, | |
| 2941 | − ctx->chain, rule, NULL); | |
| 2960 | + event, flags, ctx->family, ctx->table, | |
| 2961 | + ctx->chain, rule, handle); | |
| 2942 | 2962 | if (err < 0) { |
| 2943 | 2963 | kfree_skb(skb); |
| 2944 | 2964 | goto err; |
| @@ -2964,6 +2984,7 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, · 19 unmodified lines | ||
| 2964 | 2984 | struct net *net = sock_net(skb->sk); |
| 2965 | 2985 | const struct nft_rule *rule, *prule; |
| 2966 | 2986 | unsigned int s_idx = cb->args[0]; |
| 2987 | + u64 handle; | |
| 2967 | 2988 | |
| 2968 | 2989 | prule = NULL; |
| 2969 | 2990 | list_for_each_entry_rcu(rule, &chain->rules, list) { |
| @@ -2975,12 +2996,17 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, · 5 unmodified lines | ||
| 2975 | 2996 | memset(&cb->args[1], 0, |
| 2976 | 2997 | sizeof(cb->args) - sizeof(cb->args[0])); |
| 2977 | 2998 | } |
| 2999 | + if (prule) | |
| 3000 | + handle = prule->handle; | |
| 3001 | + else | |
| 3002 | + handle = 0; | |
| 3003 | + | |
| 2978 | 3004 | if (nf_tables_fill_rule_info(skb, net, NETLINK_CB(cb->skb).portid, |
| 2979 | 3005 | cb->nlh->nlmsg_seq, |
| 2980 | 3006 | NFT_MSG_NEWRULE, |
| 2981 | 3007 | NLM_F_MULTI | NLM_F_APPEND, |
| 2982 | 3008 | table->family, |
| 2983 | − table, chain, rule, prule) < 0) | |
| 3009 | + table, chain, rule, handle) < 0) | |
| 2984 | 3010 | return 1; |
| 2985 | 3011 | |
| 2986 | 3012 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
| @@ -3143,7 +3169,7 @@ static int nf_tables_getrule(struct sk_buff *skb, const struct nfnl_info *info, · 156 unmodified lines | ||
| 3143 | 3169 | |
| 3144 | 3170 | err = nf_tables_fill_rule_info(skb2, net, NETLINK_CB(skb).portid, |
| 3145 | 3171 | info->nlh->nlmsg_seq, NFT_MSG_NEWRULE, 0, |
| 3146 | − family, table, chain, rule, NULL); | |
| 3172 | + family, table, chain, rule, 0); | |
| 3147 | 3173 | if (err < 0) |
| 3148 | 3174 | goto err_fill_rule_info; |
| 3149 | 3175 | |
| @@ -3403,17 +3429,15 @@ static int nf_tables_newrule(struct sk_buff *skb, const struct nfnl_info *info, · 253 unmodified lines | ||
| 3403 | 3429 | } |
| 3404 | 3430 | |
| 3405 | 3431 | if (info->nlh->nlmsg_flags & NLM_F_REPLACE) { |
| 3432 | + err = nft_delrule(&ctx, old_rule); | |
| 3433 | + if (err < 0) | |
| 3434 | + goto err_destroy_flow_rule; | |
| 3435 | + | |
| 3406 | 3436 | trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); |
| 3407 | 3437 | if (trans == NULL) { |
| 3408 | 3438 | err = -ENOMEM; |
| 3409 | 3439 | goto err_destroy_flow_rule; |
| 3410 | 3440 | } |
| 3411 | − err = nft_delrule(&ctx, old_rule); | |
| 3412 | − if (err < 0) { | |
| 3413 | − nft_trans_destroy(trans); | |
| 3414 | − goto err_destroy_flow_rule; | |
| 3415 | − } | |
| 3416 | − | |
| 3417 | 3441 | list_add_tail_rcu(&rule->list, &old_rule->list); |
| 3418 | 3442 | } else { |
| 3419 | 3443 | trans = nft_trans_rule_add(&ctx, NFT_MSG_NEWRULE, rule); |
| @@ -3943,8 +3967,9 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx, · 523 unmodified lines | ||
| 3943 | 3967 | gfp_t gfp_flags) |
| 3944 | 3968 | { |
| 3945 | 3969 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
| 3946 | − struct sk_buff *skb; | |
| 3947 | 3970 | u32 portid = ctx->portid; |
| 3971 | + struct sk_buff *skb; | |
| 3972 | + u16 flags = 0; | |
| 3948 | 3973 | int err; |
| 3949 | 3974 | |
| 3950 | 3975 | if (!ctx->report && |
| @@ -3955,7 +3980,10 @@ static void nf_tables_set_notify(const struct nft_ctx *ctx, · 4 unmodified lines | ||
| 3955 | 3980 | if (skb == NULL) |
| 3956 | 3981 | goto err; |
| 3957 | 3982 | |
| 3958 | − err = nf_tables_fill_set(skb, ctx, set, event, 0); | |
| 3983 | + if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | |
| 3984 | + flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | |
| 3985 | + | |
| 3986 | + err = nf_tables_fill_set(skb, ctx, set, event, flags); | |
| 3959 | 3987 | if (err < 0) { |
| 3960 | 3988 | kfree_skb(skb); |
| 3961 | 3989 | goto err; |
| @@ -5231,12 +5259,13 @@ static int nf_tables_getsetelem(struct sk_buff *skb, · 1269 unmodified lines | ||
| 5231 | 5259 | static void nf_tables_setelem_notify(const struct nft_ctx *ctx, |
| 5232 | 5260 | const struct nft_set *set, |
| 5233 | 5261 | const struct nft_set_elem *elem, |
| 5234 | − int event, u16 flags) | |
| 5262 | + int event) | |
| 5235 | 5263 | { |
| 5236 | 5264 | struct nftables_pernet *nft_net; |
| 5237 | 5265 | struct net *net = ctx->net; |
| 5238 | 5266 | u32 portid = ctx->portid; |
| 5239 | 5267 | struct sk_buff *skb; |
| 5268 | + u16 flags = 0; | |
| 5240 | 5269 | int err; |
| 5241 | 5270 | |
| 5242 | 5271 | if (!ctx->report && !nfnetlink_has_listeners(net, NFNLGRP_NFTABLES)) |
| @@ -5246,6 +5275,9 @@ static void nf_tables_setelem_notify(const struct nft_ctx *ctx, · 3 unmodified lines | ||
| 5246 | 5275 | if (skb == NULL) |
| 5247 | 5276 | goto err; |
| 5248 | 5277 | |
| 5278 | + if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | |
| 5279 | + flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | |
| 5280 | + | |
| 5249 | 5281 | err = nf_tables_fill_setelem_info(skb, ctx, 0, portid, event, flags, |
| 5250 | 5282 | set, elem); |
| 5251 | 5283 | if (err < 0) { |
| @@ -6921,7 +6953,7 @@ static int nf_tables_delobj(struct sk_buff *skb, const struct nfnl_info *info, · 1669 unmodified lines | ||
| 6921 | 6953 | |
| 6922 | 6954 | void nft_obj_notify(struct net *net, const struct nft_table *table, |
| 6923 | 6955 | struct nft_object *obj, u32 portid, u32 seq, int event, |
| 6924 | − int family, int report, gfp_t gfp) | |
| 6956 | + u16 flags, int family, int report, gfp_t gfp) | |
| 6925 | 6957 | { |
| 6926 | 6958 | struct nftables_pernet *nft_net = nft_pernet(net); |
| 6927 | 6959 | struct sk_buff *skb; |
| @@ -6946,8 +6978,9 @@ void nft_obj_notify(struct net *net, const struct nft_table *table, · 18 unmodified lines | ||
| 6946 | 6978 | if (skb == NULL) |
| 6947 | 6979 | goto err; |
| 6948 | 6980 | |
| 6949 | − err = nf_tables_fill_obj_info(skb, net, portid, seq, event, 0, family, | |
| 6950 | − table, obj, false); | |
| 6981 | + err = nf_tables_fill_obj_info(skb, net, portid, seq, event, | |
| 6982 | + flags & (NLM_F_CREATE | NLM_F_EXCL), | |
| 6983 | + family, table, obj, false); | |
| 6951 | 6984 | if (err < 0) { |
| 6952 | 6985 | kfree_skb(skb); |
| 6953 | 6986 | goto err; |
| @@ -6964,7 +6997,7 @@ static void nf_tables_obj_notify(const struct nft_ctx *ctx, · 10 unmodified lines | ||
| 6964 | 6997 | struct nft_object *obj, int event) |
| 6965 | 6998 | { |
| 6966 | 6999 | nft_obj_notify(ctx->net, ctx->table, obj, ctx->portid, ctx->seq, event, |
| 6967 | − ctx->family, ctx->report, GFP_KERNEL); | |
| 7000 | + ctx->flags, ctx->family, ctx->report, GFP_KERNEL); | |
| 6968 | 7001 | } |
| 6969 | 7002 | |
| 6970 | 7003 | /* |
| @@ -7745,6 +7778,7 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, · 774 unmodified lines | ||
| 7745 | 7778 | { |
| 7746 | 7779 | struct nftables_pernet *nft_net = nft_pernet(ctx->net); |
| 7747 | 7780 | struct sk_buff *skb; |
| 7781 | + u16 flags = 0; | |
| 7748 | 7782 | int err; |
| 7749 | 7783 | |
| 7750 | 7784 | if (!ctx->report && |
| @@ -7755,8 +7789,11 @@ static void nf_tables_flowtable_notify(struct nft_ctx *ctx, · 4 unmodified lines | ||
| 7755 | 7789 | if (skb == NULL) |
| 7756 | 7790 | goto err; |
| 7757 | 7791 | |
| 7792 | + if (ctx->flags & (NLM_F_CREATE | NLM_F_EXCL)) | |
| 7793 | + flags |= ctx->flags & (NLM_F_CREATE | NLM_F_EXCL); | |
| 7794 | + | |
| 7758 | 7795 | err = nf_tables_fill_flowtable_info(skb, ctx->net, ctx->portid, |
| 7759 | − ctx->seq, event, 0, | |
| 7796 | + ctx->seq, event, flags, | |
| 7760 | 7797 | ctx->family, flowtable, hook_list); |
| 7761 | 7798 | if (err < 0) { |
| 7762 | 7799 | kfree_skb(skb); |
| @@ -8634,7 +8671,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) · 871 unmodified lines | ||
| 8634 | 8671 | nft_setelem_activate(net, te->set, &te->elem); |
| 8635 | 8672 | nf_tables_setelem_notify(&trans->ctx, te->set, |
| 8636 | 8673 | &te->elem, |
| 8637 | − NFT_MSG_NEWSETELEM, 0); | |
| 8674 | + NFT_MSG_NEWSETELEM); | |
| 8638 | 8675 | nft_trans_destroy(trans); |
| 8639 | 8676 | break; |
| 8640 | 8677 | case NFT_MSG_DELSETELEM: |
| @@ -8642,7 +8679,7 @@ static int nf_tables_commit(struct net *net, struct sk_buff *skb) · 1 unmodified line | ||
| 8642 | 8679 | |
| 8643 | 8680 | nf_tables_setelem_notify(&trans->ctx, te->set, |
| 8644 | 8681 | &te->elem, |
| 8645 | − NFT_MSG_DELSETELEM, 0); | |
| 8682 | + NFT_MSG_DELSETELEM); | |
| 8646 | 8683 | nft_setelem_remove(net, te->set, &te->elem); |
| 8647 | 8684 | if (!nft_setelem_is_catchall(te->set, &te->elem)) { |
| 8648 | 8685 | atomic_dec(&te->set->nelems); |
| @@ -60,7 +60,7 @@ static void nft_quota_obj_eval(struct nft_object *obj, · 59 unmodified lines | ||
| 60 | 60 | if (overquota && |
| 61 | 61 | !test_and_set_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags)) |
| 62 | 62 | nft_obj_notify(nft_net(pkt), obj->key.table, obj, 0, 0, |
| 63 | − NFT_MSG_NEWOBJ, nft_pf(pkt), 0, GFP_ATOMIC); | |
| 63 | + NFT_MSG_NEWOBJ, 0, nft_pf(pkt), 0, GFP_ATOMIC); | |
| 64 | 64 | } |
| 65 | 65 | |
| 66 | 66 | static int nft_quota_do_init(const struct nlattr * const tb[], |
| @@ -594,7 +594,10 @@ static int netlink_insert(struct sock *sk, u32 portid) · 593 unmodified lines | ||
| 594 | 594 | |
| 595 | 595 | /* We need to ensure that the socket is hashed and visible. */ |
| 596 | 596 | smp_wmb(); |
| 597 | − nlk_sk(sk)->bound = portid; | |
| 597 | + /* Paired with lockless reads from netlink_bind(), | |
| 598 | + * netlink_connect() and netlink_sendmsg(). | |
| 599 | + */ | |
| 600 | + WRITE_ONCE(nlk_sk(sk)->bound, portid); | |
| 598 | 601 | |
| 599 | 602 | err: |
| 600 | 603 | release_sock(sk); |
| @@ -1012,7 +1015,8 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, · 411 unmodified lines | ||
| 1012 | 1015 | if (nlk->ngroups < BITS_PER_LONG) |
| 1013 | 1016 | groups &= (1UL << nlk->ngroups) - 1; |
| 1014 | 1017 | |
| 1015 | − bound = nlk->bound; | |
| 1018 | + /* Paired with WRITE_ONCE() in netlink_insert() */ | |
| 1019 | + bound = READ_ONCE(nlk->bound); | |
| 1016 | 1020 | if (bound) { |
| 1017 | 1021 | /* Ensure nlk->portid is up-to-date. */ |
| 1018 | 1022 | smp_rmb(); |
| @@ -1098,8 +1102,9 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, · 79 unmodified lines | ||
| 1098 | 1102 | |
| 1099 | 1103 | /* No need for barriers here as we return to user-space without |
| 1100 | 1104 | * using any of the bound attributes. |
| 1105 | + * Paired with WRITE_ONCE() in netlink_insert(). | |
| 1101 | 1106 | */ |
| 1102 | − if (!nlk->bound) | |
| 1107 | + if (!READ_ONCE(nlk->bound)) | |
| 1103 | 1108 | err = netlink_autobind(sock); |
| 1104 | 1109 | |
| 1105 | 1110 | if (err == 0) { |
| @@ -1888,7 +1893,8 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) · 782 unmodified lines | ||
| 1888 | 1893 | dst_group = nlk->dst_group; |
| 1889 | 1894 | } |
| 1890 | 1895 | |
| 1891 | − if (!nlk->bound) { | |
| 1896 | + /* Paired with WRITE_ONCE() in netlink_insert() */ | |
| 1897 | + if (!READ_ONCE(nlk->bound)) { | |
| 1892 | 1898 | err = netlink_autobind(sock); |
| 1893 | 1899 | if (err) |
| 1894 | 1900 | goto out; |
| @@ -233,6 +233,9 @@ int fifo_set_limit(struct Qdisc *q, unsigned int limit) · 232 unmodified lines | ||
| 233 | 233 | if (strncmp(q->ops->id + 1, "fifo", 4) != 0) |
| 234 | 234 | return 0; |
| 235 | 235 | |
| 236 | + if (!q->ops->change) | |
| 237 | + return 0; | |
| 238 | + | |
| 236 | 239 | nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); |
| 237 | 240 | if (nla) { |
| 238 | 241 | nla->nla_type = RTM_NEWQDISC; |
| @@ -1641,6 +1641,10 @@ static void taprio_destroy(struct Qdisc *sch) · 1640 unmodified lines | ||
| 1641 | 1641 | list_del(&q->taprio_list); |
| 1642 | 1642 | spin_unlock(&taprio_list_lock); |
| 1643 | 1643 | |
| 1644 | + /* Note that taprio_reset() might not be called if an error | |
| 1645 | + * happens in qdisc_create(), after taprio_init() has been called. | |
| 1646 | + */ | |
| 1647 | + hrtimer_cancel(&q->advance_timer); | |
| 1644 | 1648 | |
| 1645 | 1649 | taprio_disable_offload(dev, q, NULL); |
| 1646 | 1650 | |
| @@ -2882,6 +2882,9 @@ static int unix_shutdown(struct socket *sock, int mode) · 2881 unmodified lines | ||
| 2882 | 2882 | |
| 2883 | 2883 | unix_state_lock(sk); |
| 2884 | 2884 | sk->sk_shutdown |= mode; |
| 2885 | + if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && | |
| 2886 | + mode == SHUTDOWN_MASK) | |
| 2887 | + sk->sk_state = TCP_CLOSE; | |
| 2885 | 2888 | other = unix_peer(sk); |
| 2886 | 2889 | if (other) |
| 2887 | 2890 | sock_hold(other); |
| @@ -2904,12 +2907,10 @@ static int unix_shutdown(struct socket *sock, int mode) · 16 unmodified lines | ||
| 2904 | 2907 | other->sk_shutdown |= peer_mode; |
| 2905 | 2908 | unix_state_unlock(other); |
| 2906 | 2909 | other->sk_state_change(other); |
| 2907 | − if (peer_mode == SHUTDOWN_MASK) { | |
| 2910 | + if (peer_mode == SHUTDOWN_MASK) | |
| 2908 | 2911 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_HUP); |
| 2909 | − other->sk_state = TCP_CLOSE; | |
| 2910 | − } else if (peer_mode & RCV_SHUTDOWN) { | |
| 2912 | + else if (peer_mode & RCV_SHUTDOWN) | |
| 2911 | 2913 | sk_wake_async(other, SOCK_WAKE_WAITD, POLL_IN); |
| 2912 | − } | |
| 2913 | 2914 | } |
| 2914 | 2915 | if (other) |
| 2915 | 2916 | sock_put(other); |
| @@ -1961,24 +1961,65 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb, · 1960 unmodified lines | ||
| 1961 | 1961 | return skb; |
| 1962 | 1962 | } |
| 1963 | 1963 | |
| 1964 | +static int xfrm_notify_userpolicy(struct net *net) | |
| 1965 | +{ | |
| 1966 | + struct xfrm_userpolicy_default *up; | |
| 1967 | + int len = NLMSG_ALIGN(sizeof(*up)); | |
| 1968 | + struct nlmsghdr *nlh; | |
| 1969 | + struct sk_buff *skb; | |
| 1970 | + int err; | |
| 1971 | + | |
| 1972 | + skb = nlmsg_new(len, GFP_ATOMIC); | |
| 1973 | + if (skb == NULL) | |
| 1974 | + return -ENOMEM; | |
| 1975 | + | |
| 1976 | + nlh = nlmsg_put(skb, 0, 0, XFRM_MSG_GETDEFAULT, sizeof(*up), 0); | |
| 1977 | + if (nlh == NULL) { | |
| 1978 | + kfree_skb(skb); | |
| 1979 | + return -EMSGSIZE; | |
| 1980 | + } | |
| 1981 | + | |
| 1982 | + up = nlmsg_data(nlh); | |
| 1983 | + up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ? | |
| 1984 | + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | |
| 1985 | + up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ? | |
| 1986 | + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | |
| 1987 | + up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ? | |
| 1988 | + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | |
| 1989 | + | |
| 1990 | + nlmsg_end(skb, nlh); | |
| 1991 | + | |
| 1992 | + rcu_read_lock(); | |
| 1993 | + err = xfrm_nlmsg_multicast(net, skb, 0, XFRMNLGRP_POLICY); | |
| 1994 | + rcu_read_unlock(); | |
| 1995 | + | |
| 1996 | + return err; | |
| 1997 | +} | |
| 1998 | + | |
| 1964 | 1999 | static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh, |
| 1965 | 2000 | struct nlattr **attrs) |
| 1966 | 2001 | { |
| 1967 | 2002 | struct net *net = sock_net(skb->sk); |
| 1968 | 2003 | struct xfrm_userpolicy_default *up = nlmsg_data(nlh); |
| 1969 | − u8 dirmask; | |
| 1970 | − u8 old_default = net->xfrm.policy_default; | |
| 1971 | 2004 | |
| 1972 | − if (up->dirmask >= XFRM_USERPOLICY_DIRMASK_MAX) | |
| 1973 | − return -EINVAL; | |
| 2005 | + if (up->in == XFRM_USERPOLICY_BLOCK) | |
| 2006 | + net->xfrm.policy_default |= XFRM_POL_DEFAULT_IN; | |
| 2007 | + else if (up->in == XFRM_USERPOLICY_ACCEPT) | |
| 2008 | + net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_IN; | |
| 1974 | 2009 | |
| 1975 | − dirmask = (1 << up->dirmask) & XFRM_POL_DEFAULT_MASK; | |
| 2010 | + if (up->fwd == XFRM_USERPOLICY_BLOCK) | |
| 2011 | + net->xfrm.policy_default |= XFRM_POL_DEFAULT_FWD; | |
| 2012 | + else if (up->fwd == XFRM_USERPOLICY_ACCEPT) | |
| 2013 | + net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_FWD; | |
| 1976 | 2014 | |
| 1977 | − net->xfrm.policy_default = (old_default & (0xff ^ dirmask)) | |
| 1978 | − | (up->action << up->dirmask); | |
| 2015 | + if (up->out == XFRM_USERPOLICY_BLOCK) | |
| 2016 | + net->xfrm.policy_default |= XFRM_POL_DEFAULT_OUT; | |
| 2017 | + else if (up->out == XFRM_USERPOLICY_ACCEPT) | |
| 2018 | + net->xfrm.policy_default &= ~XFRM_POL_DEFAULT_OUT; | |
| 1979 | 2019 | |
| 1980 | 2020 | rt_genid_bump_all(net); |
| 1981 | 2021 | |
| 2022 | + xfrm_notify_userpolicy(net); | |
| 1982 | 2023 | return 0; |
| 1983 | 2024 | } |
| 1984 | 2025 | |
| @@ -1988,13 +2029,11 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh, · 3 unmodified lines | ||
| 1988 | 2029 | struct sk_buff *r_skb; |
| 1989 | 2030 | struct nlmsghdr *r_nlh; |
| 1990 | 2031 | struct net *net = sock_net(skb->sk); |
| 1991 | − struct xfrm_userpolicy_default *r_up, *up; | |
| 2032 | + struct xfrm_userpolicy_default *r_up; | |
| 1992 | 2033 | int len = NLMSG_ALIGN(sizeof(struct xfrm_userpolicy_default)); |
| 1993 | 2034 | u32 portid = NETLINK_CB(skb).portid; |
| 1994 | 2035 | u32 seq = nlh->nlmsg_seq; |
| 1995 | 2036 | |
| 1996 | − up = nlmsg_data(nlh); | |
| 1997 | − | |
| 1998 | 2037 | r_skb = nlmsg_new(len, GFP_ATOMIC); |
| 1999 | 2038 | if (!r_skb) |
| 2000 | 2039 | return -ENOMEM; |
| @@ -2007,8 +2046,12 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh, · 6 unmodified lines | ||
| 2007 | 2046 | |
| 2008 | 2047 | r_up = nlmsg_data(r_nlh); |
| 2009 | 2048 | |
| 2010 | − r_up->action = ((net->xfrm.policy_default & (1 << up->dirmask)) >> up->dirmask); | |
| 2011 | − r_up->dirmask = up->dirmask; | |
| 2049 | + r_up->in = net->xfrm.policy_default & XFRM_POL_DEFAULT_IN ? | |
| 2050 | + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | |
| 2051 | + r_up->fwd = net->xfrm.policy_default & XFRM_POL_DEFAULT_FWD ? | |
| 2052 | + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | |
| 2053 | + r_up->out = net->xfrm.policy_default & XFRM_POL_DEFAULT_OUT ? | |
| 2054 | + XFRM_USERPOLICY_BLOCK : XFRM_USERPOLICY_ACCEPT; | |
| 2012 | 2055 | nlmsg_end(r_skb, r_nlh); |
| 2013 | 2056 | |
| 2014 | 2057 | return nlmsg_unicast(net->xfrm.nlsk, r_skb, portid); |
| @@ -322,17 +322,11 @@ $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h · 321 unmodified lines | ||
| 322 | 322 | |
| 323 | 323 | -include $(BPF_SAMPLES_PATH)/Makefile.target |
| 324 | 324 | |
| 325 | −VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \ | |
| 326 | − $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux) \ | |
| 327 | − ../../../../vmlinux \ | |
| 328 | − /sys/kernel/btf/vmlinux \ | |
| 329 | − /boot/vmlinux-$(shell uname -r) | |
| 325 | +VMLINUX_BTF_PATHS ?= $(abspath $(if $(O),$(O)/vmlinux)) \ | |
| 326 | + $(abspath $(if $(KBUILD_OUTPUT),$(KBUILD_OUTPUT)/vmlinux)) \ | |
| 327 | + $(abspath ./vmlinux) | |
| 330 | 328 | VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS)))) |
| 331 | 329 | |
| 332 | −ifeq ($(VMLINUX_BTF),) | |
| 333 | −$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)") | |
| 334 | −endif | |
| 335 | − | |
| 336 | 330 | $(obj)/vmlinux.h: $(VMLINUX_BTF) $(BPFTOOL) |
| 337 | 331 | ifeq ($(VMLINUX_H),) |
| 338 | 332 | $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF) format c > $@ |
| @@ -340,6 +334,11 @@ else · 1 unmodified line | ||
| 340 | 334 | $(Q)cp "$(VMLINUX_H)" $@ |
| 341 | 335 | endif |
| 342 | 336 | |
| 337 | +ifeq ($(VMLINUX_BTF),) | |
| 338 | + $(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)",\ | |
| 339 | + build the kernel or set VMLINUX_BTF variable) | |
| 340 | +endif | |
| 341 | + | |
| 343 | 342 | clean-files += vmlinux.h |
| 344 | 343 | |
| 345 | 344 | # Get Clang's default includes on this system, as opposed to those seen by |
| @@ -1,4 +1,4 @@ | ||
| 1 | −/* SPDX-License-Identifier: GPL-2.0 */ | |
| 1 | +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ | |
| 2 | 2 | /* eBPF instruction mini library */ |
| 3 | 3 | #ifndef __BPF_INSN_H |
| 4 | 4 | #define __BPF_INSN_H |
| @@ -5,11 +5,6 @@ · 4 unmodified lines | ||
| 5 | 5 | #include "xdp_sample.bpf.h" |
| 6 | 6 | #include "xdp_sample_shared.h" |
| 7 | 7 | |
| 8 | −enum { | |
| 9 | − BPF_F_BROADCAST = (1ULL << 3), | |
| 10 | − BPF_F_EXCLUDE_INGRESS = (1ULL << 4), | |
| 11 | −}; | |
| 12 | − | |
| 13 | 8 | struct { |
| 14 | 9 | __uint(type, BPF_MAP_TYPE_DEVMAP_HASH); |
| 15 | 10 | __uint(key_size, sizeof(int)); |
| @@ -126,6 +126,8 @@ static const struct nlmsg_perm nlmsg_xfrm_perms[] = · 125 unmodified lines | ||
| 126 | 126 | { XFRM_MSG_NEWSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, |
| 127 | 127 | { XFRM_MSG_GETSPDINFO, NETLINK_XFRM_SOCKET__NLMSG_READ }, |
| 128 | 128 | { XFRM_MSG_MAPPING, NETLINK_XFRM_SOCKET__NLMSG_READ }, |
| 129 | + { XFRM_MSG_SETDEFAULT, NETLINK_XFRM_SOCKET__NLMSG_WRITE }, | |
| 130 | + { XFRM_MSG_GETDEFAULT, NETLINK_XFRM_SOCKET__NLMSG_READ }, | |
| 129 | 131 | }; |
| 130 | 132 | |
| 131 | 133 | static const struct nlmsg_perm nlmsg_audit_perms[] = |
| @@ -189,7 +191,7 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) · 57 unmodified lines | ||
| 189 | 191 | * structures at the top of this file with the new mappings |
| 190 | 192 | * before updating the BUILD_BUG_ON() macro! |
| 191 | 193 | */ |
| 192 | − BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_MAPPING); | |
| 194 | + BUILD_BUG_ON(XFRM_MSG_MAX != XFRM_MSG_GETDEFAULT); | |
| 193 | 195 | err = nlmsg_perm(nlmsg_type, perm, nlmsg_xfrm_perms, |
| 194 | 196 | sizeof(nlmsg_xfrm_perms)); |
| 195 | 197 | break; |
| @@ -6894,7 +6894,8 @@ int bpf_object__load_xattr(struct bpf_object_load_attr *attr) · 6893 unmodified lines | ||
| 6894 | 6894 | |
| 6895 | 6895 | if (obj->gen_loader) { |
| 6896 | 6896 | /* reset FDs */ |
| 6897 | − btf__set_fd(obj->btf, -1); | |
| 6897 | + if (obj->btf) | |
| 6898 | + btf__set_fd(obj->btf, -1); | |
| 6898 | 6899 | for (i = 0; i < obj->nr_maps; i++) |
| 6899 | 6900 | obj->maps[i].fd = -1; |
| 6900 | 6901 | if (!err) |
| @@ -88,6 +88,7 @@ void strset__free(struct strset *set) · 87 unmodified lines | ||
| 88 | 88 | |
| 89 | 89 | hashmap__free(set->strs_hash); |
| 90 | 90 | free(set->strs_data); |
| 91 | + free(set); | |
| 91 | 92 | } |
| 92 | 93 | |
| 93 | 94 | size_t strset__data_size(const struct strset *set) |