| @@ -3065,6 +3065,81 @@ int pci_rebar_set_size(struct pci_dev *pdev, int bar, int size) · 3064 unmodified lines |
| 3065 | 3065 | return 0; |
| 3066 | 3066 | } |
| 3067 | 3067 | |
| 3068 | +/** |
| 3069 | + * pci_enable_atomic_ops_to_root - enable AtomicOp requests to root port |
| 3070 | + * @dev: the PCI device |
| 3071 | + * @cap_mask: mask of desired AtomicOp sizes, including one or more of: |
| 3072 | + * PCI_EXP_DEVCAP2_ATOMIC_COMP32 |
| 3073 | + * PCI_EXP_DEVCAP2_ATOMIC_COMP64 |
| 3074 | + * PCI_EXP_DEVCAP2_ATOMIC_COMP128 |
| 3075 | + * |
| 3076 | + * Return 0 if all upstream bridges support AtomicOp routing, egress |
| 3077 | + * blocking is disabled on all upstream ports, and the root port supports |
| 3078 | + * the requested completion capabilities (32-bit, 64-bit and/or 128-bit |
| 3079 | + * AtomicOp completion), or negative otherwise. |
| 3080 | + */ |
| 3081 | +int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask) |
| 3082 | +{ |
| 3083 | + struct pci_bus *bus = dev->bus; |
| 3084 | + struct pci_dev *bridge; |
| 3085 | + u32 cap, ctl2; |
| 3086 | + |
| 3087 | + if (!pci_is_pcie(dev)) |
| 3088 | + return -EINVAL; |
| 3089 | + |
| 3090 | + /* |
| 3091 | + * Per PCIe r4.0, sec 6.15, endpoints and root ports may be |
| 3092 | + * AtomicOp requesters. For now, we only support endpoints as |
| 3093 | + * requesters and root ports as completers. No endpoints as |
| 3094 | + * completers, and no peer-to-peer. |
| 3095 | + */ |
| 3096 | + |
| 3097 | + switch (pci_pcie_type(dev)) { |
| 3098 | + case PCI_EXP_TYPE_ENDPOINT: |
| 3099 | + case PCI_EXP_TYPE_LEG_END: |
| 3100 | + case PCI_EXP_TYPE_RC_END: |
| 3101 | + break; |
| 3102 | + default: |
| 3103 | + return -EINVAL; |
| 3104 | + } |
| 3105 | + |
| 3106 | + while (bus->parent) { |
| 3107 | + bridge = bus->self; |
| 3108 | + |
| 3109 | + pcie_capability_read_dword(bridge, PCI_EXP_DEVCAP2, &cap); |
| 3110 | + |
| 3111 | + switch (pci_pcie_type(bridge)) { |
| 3112 | + /* Ensure switch ports support AtomicOp routing */ |
| 3113 | + case PCI_EXP_TYPE_UPSTREAM: |
| 3114 | + case PCI_EXP_TYPE_DOWNSTREAM: |
| 3115 | + if (!(cap & PCI_EXP_DEVCAP2_ATOMIC_ROUTE)) |
| 3116 | + return -EINVAL; |
| 3117 | + break; |
| 3118 | + |
| 3119 | + /* Ensure root port supports all the sizes we care about */ |
| 3120 | + case PCI_EXP_TYPE_ROOT_PORT: |
| 3121 | + if ((cap & cap_mask) != cap_mask) |
| 3122 | + return -EINVAL; |
| 3123 | + break; |
| 3124 | + } |
| 3125 | + |
| 3126 | + /* Ensure upstream ports don't block AtomicOps on egress */ |
| 3127 | + if (!bridge->has_secondary_link) { |
| 3128 | + pcie_capability_read_dword(bridge, PCI_EXP_DEVCTL2, |
| 3129 | + &ctl2); |
| 3130 | + if (ctl2 & PCI_EXP_DEVCTL2_ATOMIC_EGRESS_BLOCK) |
| 3131 | + return -EINVAL; |
| 3132 | + } |
| 3133 | + |
| 3134 | + bus = bus->parent; |
| 3135 | + } |
| 3136 | + |
| 3137 | + pcie_capability_set_word(dev, PCI_EXP_DEVCTL2, |
| 3138 | + PCI_EXP_DEVCTL2_ATOMIC_REQ); |
| 3139 | + return 0; |
| 3140 | +} |
| 3141 | +EXPORT_SYMBOL(pci_enable_atomic_ops_to_root); |
| 3142 | + |
| 3068 | 3143 | /** |
| 3069 | 3144 | * pci_swizzle_interrupt_pin - swizzle INTx for device behind bridge |
| 3070 | 3145 | * @dev: the PCI device |