.. | .. |
---|
52 | 52 | #include <linux/inetdevice.h> |
---|
53 | 53 | #include <rdma/ib_cache.h> |
---|
54 | 54 | |
---|
55 | | -#define DRV_VERSION "1.0.0" |
---|
56 | | - |
---|
57 | | -const char ipoib_driver_version[] = DRV_VERSION; |
---|
58 | | - |
---|
59 | 55 | MODULE_AUTHOR("Roland Dreier"); |
---|
60 | 56 | MODULE_DESCRIPTION("IP-over-InfiniBand net driver"); |
---|
61 | 57 | MODULE_LICENSE("Dual BSD/GPL"); |
---|
.. | .. |
---|
90 | 86 | |
---|
91 | 87 | struct ib_sa_client ipoib_sa_client; |
---|
92 | 88 | |
---|
93 | | -static void ipoib_add_one(struct ib_device *device); |
---|
| 89 | +static int ipoib_add_one(struct ib_device *device); |
---|
94 | 90 | static void ipoib_remove_one(struct ib_device *device, void *client_data); |
---|
95 | 91 | static void ipoib_neigh_reclaim(struct rcu_head *rp); |
---|
96 | 92 | static struct net_device *ipoib_get_net_dev_by_params( |
---|
.. | .. |
---|
167 | 163 | if (flags & IFF_UP) |
---|
168 | 164 | continue; |
---|
169 | 165 | |
---|
170 | | - dev_change_flags(cpriv->dev, flags | IFF_UP); |
---|
| 166 | + dev_change_flags(cpriv->dev, flags | IFF_UP, NULL); |
---|
171 | 167 | } |
---|
172 | 168 | up_read(&priv->vlan_rwsem); |
---|
173 | 169 | } |
---|
.. | .. |
---|
207 | 203 | if (!(flags & IFF_UP)) |
---|
208 | 204 | continue; |
---|
209 | 205 | |
---|
210 | | - dev_change_flags(cpriv->dev, flags & ~IFF_UP); |
---|
| 206 | + dev_change_flags(cpriv->dev, flags & ~IFF_UP, NULL); |
---|
211 | 207 | } |
---|
212 | 208 | up_read(&priv->vlan_rwsem); |
---|
213 | 209 | } |
---|
.. | .. |
---|
346 | 342 | struct net_device *result; |
---|
347 | 343 | }; |
---|
348 | 344 | |
---|
349 | | -static int ipoib_upper_walk(struct net_device *upper, void *_data) |
---|
| 345 | +static int ipoib_upper_walk(struct net_device *upper, |
---|
| 346 | + struct netdev_nested_priv *priv) |
---|
350 | 347 | { |
---|
351 | | - struct ipoib_walk_data *data = _data; |
---|
| 348 | + struct ipoib_walk_data *data = (struct ipoib_walk_data *)priv->data; |
---|
352 | 349 | int ret = 0; |
---|
353 | 350 | |
---|
354 | 351 | if (ipoib_is_dev_match_addr_rcu(data->addr, upper)) { |
---|
.. | .. |
---|
372 | 369 | static struct net_device *ipoib_get_net_dev_match_addr( |
---|
373 | 370 | const struct sockaddr *addr, struct net_device *dev) |
---|
374 | 371 | { |
---|
| 372 | + struct netdev_nested_priv priv; |
---|
375 | 373 | struct ipoib_walk_data data = { |
---|
376 | 374 | .addr = addr, |
---|
377 | 375 | }; |
---|
378 | 376 | |
---|
| 377 | + priv.data = (void *)&data; |
---|
379 | 378 | rcu_read_lock(); |
---|
380 | 379 | if (ipoib_is_dev_match_addr_rcu(addr, dev)) { |
---|
381 | 380 | dev_hold(dev); |
---|
.. | .. |
---|
383 | 382 | goto out; |
---|
384 | 383 | } |
---|
385 | 384 | |
---|
386 | | - netdev_walk_all_upper_dev_rcu(dev, ipoib_upper_walk, &data); |
---|
| 385 | + netdev_walk_all_upper_dev_rcu(dev, ipoib_upper_walk, &priv); |
---|
387 | 386 | out: |
---|
388 | 387 | rcu_read_unlock(); |
---|
389 | 388 | return data.result; |
---|
.. | .. |
---|
483 | 482 | if (ret) |
---|
484 | 483 | return NULL; |
---|
485 | 484 | |
---|
486 | | - if (!dev_list) |
---|
487 | | - return NULL; |
---|
488 | | - |
---|
489 | 485 | /* See if we can find a unique device matching the L2 parameters */ |
---|
490 | 486 | matches = __ipoib_get_net_dev_by_params(dev_list, port, pkey_index, |
---|
491 | 487 | gid, NULL, &net_dev); |
---|
.. | .. |
---|
509 | 505 | default: |
---|
510 | 506 | dev_warn_ratelimited(&dev->dev, |
---|
511 | 507 | "duplicate IP address detected\n"); |
---|
512 | | - /* Fall through */ |
---|
| 508 | + fallthrough; |
---|
513 | 509 | case 1: |
---|
514 | 510 | return net_dev; |
---|
515 | 511 | } |
---|
.. | .. |
---|
533 | 529 | "will cause multicast packet drops\n"); |
---|
534 | 530 | netdev_update_features(dev); |
---|
535 | 531 | dev_set_mtu(dev, ipoib_cm_max_mtu(dev)); |
---|
| 532 | + netif_set_real_num_tx_queues(dev, 1); |
---|
536 | 533 | rtnl_unlock(); |
---|
537 | 534 | priv->tx_wr.wr.send_flags &= ~IB_SEND_IP_CSUM; |
---|
538 | 535 | |
---|
.. | .. |
---|
544 | 541 | clear_bit(IPOIB_FLAG_ADMIN_CM, &priv->flags); |
---|
545 | 542 | netdev_update_features(dev); |
---|
546 | 543 | dev_set_mtu(dev, min(priv->mcast_mtu, dev->mtu)); |
---|
| 544 | + netif_set_real_num_tx_queues(dev, dev->num_tx_queues); |
---|
547 | 545 | rtnl_unlock(); |
---|
548 | 546 | ipoib_flush_paths(dev); |
---|
549 | 547 | return (!rtnl_trylock()) ? -EBUSY : 0; |
---|
.. | .. |
---|
613 | 611 | while ((skb = __skb_dequeue(&path->queue))) |
---|
614 | 612 | dev_kfree_skb_irq(skb); |
---|
615 | 613 | |
---|
616 | | - ipoib_dbg(ipoib_priv(dev), "path_free\n"); |
---|
| 614 | + ipoib_dbg(ipoib_priv(dev), "%s\n", __func__); |
---|
617 | 615 | |
---|
618 | 616 | /* remove all neigh connected to this path */ |
---|
619 | 617 | ipoib_del_neighs_by_gid(dev, path->pathrec.dgid.raw); |
---|
.. | .. |
---|
1182 | 1180 | return NETDEV_TX_OK; |
---|
1183 | 1181 | } |
---|
1184 | 1182 | |
---|
1185 | | -static void ipoib_timeout(struct net_device *dev) |
---|
| 1183 | +static void ipoib_timeout(struct net_device *dev, unsigned int txqueue) |
---|
1186 | 1184 | { |
---|
1187 | 1185 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
---|
1188 | 1186 | |
---|
.. | .. |
---|
1643 | 1641 | { |
---|
1644 | 1642 | struct ipoib_dev_priv *priv = ipoib_priv(dev); |
---|
1645 | 1643 | |
---|
1646 | | - ipoib_dbg(priv, "ipoib_neigh_hash_uninit\n"); |
---|
| 1644 | + ipoib_dbg(priv, "%s\n", __func__); |
---|
1647 | 1645 | init_completion(&priv->ntbl.deleted); |
---|
1648 | 1646 | |
---|
1649 | 1647 | cancel_delayed_work_sync(&priv->neigh_reap_task); |
---|
.. | .. |
---|
1825 | 1823 | * running ensures the it will not add more work. |
---|
1826 | 1824 | */ |
---|
1827 | 1825 | rtnl_lock(); |
---|
1828 | | - dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP); |
---|
| 1826 | + dev_change_flags(priv->dev, priv->dev->flags & ~IFF_UP, NULL); |
---|
1829 | 1827 | rtnl_unlock(); |
---|
1830 | 1828 | |
---|
1831 | 1829 | /* ipoib_event() cannot be running once this returns */ |
---|
.. | .. |
---|
1864 | 1862 | priv->port); |
---|
1865 | 1863 | return result; |
---|
1866 | 1864 | } |
---|
1867 | | - priv->max_ib_mtu = ib_mtu_enum_to_int(attr.max_mtu); |
---|
| 1865 | + priv->max_ib_mtu = rdma_mtu_from_attr(priv->ca, priv->port, &attr); |
---|
1868 | 1866 | |
---|
1869 | 1867 | result = ib_query_pkey(priv->ca, priv->port, 0, &priv->pkey); |
---|
1870 | 1868 | if (result) { |
---|
.. | .. |
---|
1897 | 1895 | |
---|
1898 | 1896 | priv->max_ib_mtu = ppriv->max_ib_mtu; |
---|
1899 | 1897 | set_bit(IPOIB_FLAG_SUBINTERFACE, &priv->flags); |
---|
1900 | | - memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, INFINIBAND_ALEN); |
---|
1901 | | - memcpy(&priv->local_gid, &ppriv->local_gid, sizeof(priv->local_gid)); |
---|
| 1898 | + if (memchr_inv(priv->dev->dev_addr, 0, INFINIBAND_ALEN)) |
---|
| 1899 | + memcpy(&priv->local_gid, priv->dev->dev_addr + 4, |
---|
| 1900 | + sizeof(priv->local_gid)); |
---|
| 1901 | + else { |
---|
| 1902 | + memcpy(priv->dev->dev_addr, ppriv->dev->dev_addr, |
---|
| 1903 | + INFINIBAND_ALEN); |
---|
| 1904 | + memcpy(&priv->local_gid, &ppriv->local_gid, |
---|
| 1905 | + sizeof(priv->local_gid)); |
---|
| 1906 | + } |
---|
1902 | 1907 | } |
---|
1903 | 1908 | |
---|
1904 | 1909 | static int ipoib_ndo_init(struct net_device *ndev) |
---|
1905 | 1910 | { |
---|
1906 | 1911 | struct ipoib_dev_priv *priv = ipoib_priv(ndev); |
---|
1907 | 1912 | int rc; |
---|
| 1913 | + struct rdma_netdev *rn = netdev_priv(ndev); |
---|
1908 | 1914 | |
---|
1909 | 1915 | if (priv->parent) { |
---|
1910 | 1916 | ipoib_child_init(ndev); |
---|
.. | .. |
---|
1917 | 1923 | /* MTU will be reset when mcast join happens */ |
---|
1918 | 1924 | ndev->mtu = IPOIB_UD_MTU(priv->max_ib_mtu); |
---|
1919 | 1925 | priv->mcast_mtu = priv->admin_mtu = ndev->mtu; |
---|
| 1926 | + rn->mtu = priv->mcast_mtu; |
---|
1920 | 1927 | ndev->max_mtu = IPOIB_CM_MTU; |
---|
1921 | 1928 | |
---|
1922 | 1929 | ndev->neigh_priv_len = sizeof(struct ipoib_neigh); |
---|
.. | .. |
---|
2023 | 2030 | return ib_set_vf_guid(priv->ca, vf, priv->port, guid, type); |
---|
2024 | 2031 | } |
---|
2025 | 2032 | |
---|
| 2033 | +static int ipoib_get_vf_guid(struct net_device *dev, int vf, |
---|
| 2034 | + struct ifla_vf_guid *node_guid, |
---|
| 2035 | + struct ifla_vf_guid *port_guid) |
---|
| 2036 | +{ |
---|
| 2037 | + struct ipoib_dev_priv *priv = ipoib_priv(dev); |
---|
| 2038 | + |
---|
| 2039 | + return ib_get_vf_guid(priv->ca, vf, priv->port, node_guid, port_guid); |
---|
| 2040 | +} |
---|
| 2041 | + |
---|
2026 | 2042 | static int ipoib_get_vf_stats(struct net_device *dev, int vf, |
---|
2027 | 2043 | struct ifla_vf_stats *vf_stats) |
---|
2028 | 2044 | { |
---|
.. | .. |
---|
2049 | 2065 | .ndo_set_vf_link_state = ipoib_set_vf_link_state, |
---|
2050 | 2066 | .ndo_get_vf_config = ipoib_get_vf_config, |
---|
2051 | 2067 | .ndo_get_vf_stats = ipoib_get_vf_stats, |
---|
| 2068 | + .ndo_get_vf_guid = ipoib_get_vf_guid, |
---|
2052 | 2069 | .ndo_set_vf_guid = ipoib_set_vf_guid, |
---|
2053 | 2070 | .ndo_set_mac_address = ipoib_set_mac, |
---|
2054 | 2071 | .ndo_get_stats64 = ipoib_get_stats, |
---|
.. | .. |
---|
2070 | 2087 | .ndo_do_ioctl = ipoib_ioctl, |
---|
2071 | 2088 | }; |
---|
2072 | 2089 | |
---|
| 2090 | +static const struct net_device_ops ipoib_netdev_default_pf = { |
---|
| 2091 | + .ndo_init = ipoib_dev_init_default, |
---|
| 2092 | + .ndo_uninit = ipoib_dev_uninit_default, |
---|
| 2093 | + .ndo_open = ipoib_ib_dev_open_default, |
---|
| 2094 | + .ndo_stop = ipoib_ib_dev_stop_default, |
---|
| 2095 | +}; |
---|
| 2096 | + |
---|
2073 | 2097 | void ipoib_setup_common(struct net_device *dev) |
---|
2074 | 2098 | { |
---|
2075 | 2099 | dev->header_ops = &ipoib_header_ops; |
---|
| 2100 | + dev->netdev_ops = &ipoib_netdev_default_pf; |
---|
2076 | 2101 | |
---|
2077 | 2102 | ipoib_set_ethtool_ops(dev); |
---|
2078 | 2103 | |
---|
.. | .. |
---|
2122 | 2147 | INIT_DELAYED_WORK(&priv->neigh_reap_task, ipoib_reap_neigh); |
---|
2123 | 2148 | } |
---|
2124 | 2149 | |
---|
2125 | | -static const struct net_device_ops ipoib_netdev_default_pf = { |
---|
2126 | | - .ndo_init = ipoib_dev_init_default, |
---|
2127 | | - .ndo_uninit = ipoib_dev_uninit_default, |
---|
2128 | | - .ndo_open = ipoib_ib_dev_open_default, |
---|
2129 | | - .ndo_stop = ipoib_ib_dev_stop_default, |
---|
2130 | | -}; |
---|
2131 | | - |
---|
2132 | | -static struct net_device |
---|
2133 | | -*ipoib_create_netdev_default(struct ib_device *hca, |
---|
2134 | | - const char *name, |
---|
2135 | | - unsigned char name_assign_type, |
---|
2136 | | - void (*setup)(struct net_device *)) |
---|
| 2150 | +static struct net_device *ipoib_alloc_netdev(struct ib_device *hca, u8 port, |
---|
| 2151 | + const char *name) |
---|
2137 | 2152 | { |
---|
2138 | 2153 | struct net_device *dev; |
---|
2139 | | - struct rdma_netdev *rn; |
---|
2140 | 2154 | |
---|
2141 | | - dev = alloc_netdev((int)sizeof(struct rdma_netdev), |
---|
2142 | | - name, |
---|
2143 | | - name_assign_type, setup); |
---|
| 2155 | + dev = rdma_alloc_netdev(hca, port, RDMA_NETDEV_IPOIB, name, |
---|
| 2156 | + NET_NAME_UNKNOWN, ipoib_setup_common); |
---|
| 2157 | + if (!IS_ERR(dev) || PTR_ERR(dev) != -EOPNOTSUPP) |
---|
| 2158 | + return dev; |
---|
| 2159 | + |
---|
| 2160 | + dev = alloc_netdev(sizeof(struct rdma_netdev), name, NET_NAME_UNKNOWN, |
---|
| 2161 | + ipoib_setup_common); |
---|
2144 | 2162 | if (!dev) |
---|
2145 | | - return NULL; |
---|
2146 | | - |
---|
2147 | | - rn = netdev_priv(dev); |
---|
2148 | | - |
---|
2149 | | - rn->send = ipoib_send; |
---|
2150 | | - rn->attach_mcast = ipoib_mcast_attach; |
---|
2151 | | - rn->detach_mcast = ipoib_mcast_detach; |
---|
2152 | | - rn->hca = hca; |
---|
2153 | | - dev->netdev_ops = &ipoib_netdev_default_pf; |
---|
2154 | | - |
---|
| 2163 | + return ERR_PTR(-ENOMEM); |
---|
2155 | 2164 | return dev; |
---|
2156 | 2165 | } |
---|
2157 | 2166 | |
---|
2158 | | -static struct net_device *ipoib_get_netdev(struct ib_device *hca, u8 port, |
---|
2159 | | - const char *name) |
---|
| 2167 | +int ipoib_intf_init(struct ib_device *hca, u8 port, const char *name, |
---|
| 2168 | + struct net_device *dev) |
---|
2160 | 2169 | { |
---|
2161 | | - struct net_device *dev; |
---|
2162 | | - |
---|
2163 | | - if (hca->alloc_rdma_netdev) { |
---|
2164 | | - dev = hca->alloc_rdma_netdev(hca, port, |
---|
2165 | | - RDMA_NETDEV_IPOIB, name, |
---|
2166 | | - NET_NAME_UNKNOWN, |
---|
2167 | | - ipoib_setup_common); |
---|
2168 | | - if (IS_ERR_OR_NULL(dev) && PTR_ERR(dev) != -EOPNOTSUPP) |
---|
2169 | | - return NULL; |
---|
2170 | | - } |
---|
2171 | | - |
---|
2172 | | - if (!hca->alloc_rdma_netdev || PTR_ERR(dev) == -EOPNOTSUPP) |
---|
2173 | | - dev = ipoib_create_netdev_default(hca, name, NET_NAME_UNKNOWN, |
---|
2174 | | - ipoib_setup_common); |
---|
2175 | | - |
---|
2176 | | - return dev; |
---|
2177 | | -} |
---|
2178 | | - |
---|
2179 | | -struct ipoib_dev_priv *ipoib_intf_alloc(struct ib_device *hca, u8 port, |
---|
2180 | | - const char *name) |
---|
2181 | | -{ |
---|
2182 | | - struct net_device *dev; |
---|
| 2170 | + struct rdma_netdev *rn = netdev_priv(dev); |
---|
2183 | 2171 | struct ipoib_dev_priv *priv; |
---|
2184 | | - struct rdma_netdev *rn; |
---|
| 2172 | + int rc; |
---|
2185 | 2173 | |
---|
2186 | 2174 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
---|
2187 | 2175 | if (!priv) |
---|
2188 | | - return NULL; |
---|
| 2176 | + return -ENOMEM; |
---|
2189 | 2177 | |
---|
2190 | 2178 | priv->ca = hca; |
---|
2191 | 2179 | priv->port = port; |
---|
2192 | 2180 | |
---|
2193 | | - dev = ipoib_get_netdev(hca, port, name); |
---|
2194 | | - if (!dev) |
---|
2195 | | - goto free_priv; |
---|
| 2181 | + rc = rdma_init_netdev(hca, port, RDMA_NETDEV_IPOIB, name, |
---|
| 2182 | + NET_NAME_UNKNOWN, ipoib_setup_common, dev); |
---|
| 2183 | + if (rc) { |
---|
| 2184 | + if (rc != -EOPNOTSUPP) |
---|
| 2185 | + goto out; |
---|
| 2186 | + |
---|
| 2187 | + rn->send = ipoib_send; |
---|
| 2188 | + rn->attach_mcast = ipoib_mcast_attach; |
---|
| 2189 | + rn->detach_mcast = ipoib_mcast_detach; |
---|
| 2190 | + rn->hca = hca; |
---|
| 2191 | + |
---|
| 2192 | + rc = netif_set_real_num_tx_queues(dev, 1); |
---|
| 2193 | + if (rc) |
---|
| 2194 | + goto out; |
---|
| 2195 | + |
---|
| 2196 | + rc = netif_set_real_num_rx_queues(dev, 1); |
---|
| 2197 | + if (rc) |
---|
| 2198 | + goto out; |
---|
| 2199 | + } |
---|
2196 | 2200 | |
---|
2197 | 2201 | priv->rn_ops = dev->netdev_ops; |
---|
2198 | 2202 | |
---|
2199 | | - /* fixme : should be after the query_cap */ |
---|
2200 | | - if (priv->hca_caps & IB_DEVICE_VIRTUAL_FUNCTION) |
---|
| 2203 | + if (hca->attrs.device_cap_flags & IB_DEVICE_VIRTUAL_FUNCTION) |
---|
2201 | 2204 | dev->netdev_ops = &ipoib_netdev_ops_vf; |
---|
2202 | 2205 | else |
---|
2203 | 2206 | dev->netdev_ops = &ipoib_netdev_ops_pf; |
---|
2204 | 2207 | |
---|
2205 | | - rn = netdev_priv(dev); |
---|
2206 | 2208 | rn->clnt_priv = priv; |
---|
2207 | | - |
---|
2208 | 2209 | /* |
---|
2209 | 2210 | * Only the child register_netdev flows can handle priv_destructor |
---|
2210 | 2211 | * being set, so we force it to NULL here and handle manually until it |
---|
.. | .. |
---|
2215 | 2216 | |
---|
2216 | 2217 | ipoib_build_priv(dev); |
---|
2217 | 2218 | |
---|
2218 | | - return priv; |
---|
2219 | | -free_priv: |
---|
| 2219 | + return 0; |
---|
| 2220 | + |
---|
| 2221 | +out: |
---|
2220 | 2222 | kfree(priv); |
---|
2221 | | - return NULL; |
---|
| 2223 | + return rc; |
---|
| 2224 | +} |
---|
| 2225 | + |
---|
| 2226 | +struct net_device *ipoib_intf_alloc(struct ib_device *hca, u8 port, |
---|
| 2227 | + const char *name) |
---|
| 2228 | +{ |
---|
| 2229 | + struct net_device *dev; |
---|
| 2230 | + int rc; |
---|
| 2231 | + |
---|
| 2232 | + dev = ipoib_alloc_netdev(hca, port, name); |
---|
| 2233 | + if (IS_ERR(dev)) |
---|
| 2234 | + return dev; |
---|
| 2235 | + |
---|
| 2236 | + rc = ipoib_intf_init(hca, port, name, dev); |
---|
| 2237 | + if (rc) { |
---|
| 2238 | + free_netdev(dev); |
---|
| 2239 | + return ERR_PTR(rc); |
---|
| 2240 | + } |
---|
| 2241 | + |
---|
| 2242 | + /* |
---|
| 2243 | + * Upon success the caller must ensure ipoib_intf_free is called or |
---|
| 2244 | + * register_netdevice succeed'd and priv_destructor is set to |
---|
| 2245 | + * ipoib_intf_free. |
---|
| 2246 | + */ |
---|
| 2247 | + return dev; |
---|
2222 | 2248 | } |
---|
2223 | 2249 | |
---|
2224 | 2250 | void ipoib_intf_free(struct net_device *dev) |
---|
.. | .. |
---|
2398 | 2424 | return device_create_file(&dev->dev, &dev_attr_pkey); |
---|
2399 | 2425 | } |
---|
2400 | 2426 | |
---|
| 2427 | +/* |
---|
| 2428 | + * We erroneously exposed the iface's port number in the dev_id |
---|
| 2429 | + * sysfs field long after dev_port was introduced for that purpose[1], |
---|
| 2430 | + * and we need to stop everyone from relying on that. |
---|
| 2431 | + * Let's overload the shower routine for the dev_id file here |
---|
| 2432 | + * to gently bring the issue up. |
---|
| 2433 | + * |
---|
| 2434 | + * [1] https://www.spinics.net/lists/netdev/msg272123.html |
---|
| 2435 | + */ |
---|
| 2436 | +static ssize_t dev_id_show(struct device *dev, |
---|
| 2437 | + struct device_attribute *attr, char *buf) |
---|
| 2438 | +{ |
---|
| 2439 | + struct net_device *ndev = to_net_dev(dev); |
---|
| 2440 | + |
---|
| 2441 | + /* |
---|
| 2442 | + * ndev->dev_port will be equal to 0 in old kernel prior to commit |
---|
| 2443 | + * 9b8b2a323008 ("IB/ipoib: Use dev_port to expose network interface |
---|
| 2444 | + * port numbers") Zero was chosen as special case for user space |
---|
| 2445 | + * applications to fallback and query dev_id to check if it has |
---|
| 2446 | + * different value or not. |
---|
| 2447 | + * |
---|
| 2448 | + * Don't print warning in such scenario. |
---|
| 2449 | + * |
---|
| 2450 | + * https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-net_id.c#L358 |
---|
| 2451 | + */ |
---|
| 2452 | + if (ndev->dev_port && ndev->dev_id == ndev->dev_port) |
---|
| 2453 | + netdev_info_once(ndev, |
---|
| 2454 | + "\"%s\" wants to know my dev_id. Should it look at dev_port instead? See Documentation/ABI/testing/sysfs-class-net for more info.\n", |
---|
| 2455 | + current->comm); |
---|
| 2456 | + |
---|
| 2457 | + return sprintf(buf, "%#x\n", ndev->dev_id); |
---|
| 2458 | +} |
---|
| 2459 | +static DEVICE_ATTR_RO(dev_id); |
---|
| 2460 | + |
---|
| 2461 | +static int ipoib_intercept_dev_id_attr(struct net_device *dev) |
---|
| 2462 | +{ |
---|
| 2463 | + device_remove_file(&dev->dev, &dev_attr_dev_id); |
---|
| 2464 | + return device_create_file(&dev->dev, &dev_attr_dev_id); |
---|
| 2465 | +} |
---|
| 2466 | + |
---|
2401 | 2467 | static struct net_device *ipoib_add_port(const char *format, |
---|
2402 | 2468 | struct ib_device *hca, u8 port) |
---|
2403 | 2469 | { |
---|
| 2470 | + struct rtnl_link_ops *ops = ipoib_get_link_ops(); |
---|
| 2471 | + struct rdma_netdev_alloc_params params; |
---|
2404 | 2472 | struct ipoib_dev_priv *priv; |
---|
2405 | 2473 | struct net_device *ndev; |
---|
2406 | 2474 | int result; |
---|
2407 | 2475 | |
---|
2408 | | - priv = ipoib_intf_alloc(hca, port, format); |
---|
2409 | | - if (!priv) { |
---|
2410 | | - pr_warn("%s, %d: ipoib_intf_alloc failed\n", hca->name, port); |
---|
2411 | | - return ERR_PTR(-ENOMEM); |
---|
| 2476 | + ndev = ipoib_intf_alloc(hca, port, format); |
---|
| 2477 | + if (IS_ERR(ndev)) { |
---|
| 2478 | + pr_warn("%s, %d: ipoib_intf_alloc failed %ld\n", hca->name, port, |
---|
| 2479 | + PTR_ERR(ndev)); |
---|
| 2480 | + return ndev; |
---|
2412 | 2481 | } |
---|
2413 | | - ndev = priv->dev; |
---|
| 2482 | + priv = ipoib_priv(ndev); |
---|
2414 | 2483 | |
---|
2415 | 2484 | INIT_IB_EVENT_HANDLER(&priv->event_handler, |
---|
2416 | 2485 | priv->ca, ipoib_event); |
---|
.. | .. |
---|
2418 | 2487 | |
---|
2419 | 2488 | /* call event handler to ensure pkey in sync */ |
---|
2420 | 2489 | queue_work(ipoib_workqueue, &priv->flush_heavy); |
---|
| 2490 | + |
---|
| 2491 | + ndev->rtnl_link_ops = ipoib_get_link_ops(); |
---|
2421 | 2492 | |
---|
2422 | 2493 | result = register_netdev(ndev); |
---|
2423 | 2494 | if (result) { |
---|
.. | .. |
---|
2431 | 2502 | return ERR_PTR(result); |
---|
2432 | 2503 | } |
---|
2433 | 2504 | |
---|
| 2505 | + if (hca->ops.rdma_netdev_get_params) { |
---|
| 2506 | + int rc = hca->ops.rdma_netdev_get_params(hca, port, |
---|
| 2507 | + RDMA_NETDEV_IPOIB, |
---|
| 2508 | + ¶ms); |
---|
| 2509 | + |
---|
| 2510 | + if (!rc && ops->priv_size < params.sizeof_priv) |
---|
| 2511 | + ops->priv_size = params.sizeof_priv; |
---|
| 2512 | + } |
---|
2434 | 2513 | /* |
---|
2435 | 2514 | * We cannot set priv_destructor before register_netdev because we |
---|
2436 | 2515 | * need priv to be always valid during the error flow to execute |
---|
.. | .. |
---|
2439 | 2518 | */ |
---|
2440 | 2519 | ndev->priv_destructor = ipoib_intf_free; |
---|
2441 | 2520 | |
---|
| 2521 | + if (ipoib_intercept_dev_id_attr(ndev)) |
---|
| 2522 | + goto sysfs_failed; |
---|
2442 | 2523 | if (ipoib_cm_add_mode_attr(ndev)) |
---|
2443 | 2524 | goto sysfs_failed; |
---|
2444 | 2525 | if (ipoib_add_pkey_attr(ndev)) |
---|
.. | .. |
---|
2458 | 2539 | return ERR_PTR(-ENOMEM); |
---|
2459 | 2540 | } |
---|
2460 | 2541 | |
---|
2461 | | -static void ipoib_add_one(struct ib_device *device) |
---|
| 2542 | +static int ipoib_add_one(struct ib_device *device) |
---|
2462 | 2543 | { |
---|
2463 | 2544 | struct list_head *dev_list; |
---|
2464 | 2545 | struct net_device *dev; |
---|
2465 | 2546 | struct ipoib_dev_priv *priv; |
---|
2466 | | - int p; |
---|
| 2547 | + unsigned int p; |
---|
2467 | 2548 | int count = 0; |
---|
2468 | 2549 | |
---|
2469 | 2550 | dev_list = kmalloc(sizeof(*dev_list), GFP_KERNEL); |
---|
2470 | 2551 | if (!dev_list) |
---|
2471 | | - return; |
---|
| 2552 | + return -ENOMEM; |
---|
2472 | 2553 | |
---|
2473 | 2554 | INIT_LIST_HEAD(dev_list); |
---|
2474 | 2555 | |
---|
2475 | | - for (p = rdma_start_port(device); p <= rdma_end_port(device); ++p) { |
---|
| 2556 | + rdma_for_each_port (device, p) { |
---|
2476 | 2557 | if (!rdma_protocol_ib(device, p)) |
---|
2477 | 2558 | continue; |
---|
2478 | 2559 | dev = ipoib_add_port("ib%d", device, p); |
---|
.. | .. |
---|
2485 | 2566 | |
---|
2486 | 2567 | if (!count) { |
---|
2487 | 2568 | kfree(dev_list); |
---|
2488 | | - return; |
---|
| 2569 | + return -EOPNOTSUPP; |
---|
2489 | 2570 | } |
---|
2490 | 2571 | |
---|
2491 | 2572 | ib_set_client_data(device, &ipoib_client, dev_list); |
---|
| 2573 | + return 0; |
---|
2492 | 2574 | } |
---|
2493 | 2575 | |
---|
2494 | 2576 | static void ipoib_remove_one(struct ib_device *device, void *client_data) |
---|
2495 | 2577 | { |
---|
2496 | 2578 | struct ipoib_dev_priv *priv, *tmp, *cpriv, *tcpriv; |
---|
2497 | 2579 | struct list_head *dev_list = client_data; |
---|
2498 | | - |
---|
2499 | | - if (!dev_list) |
---|
2500 | | - return; |
---|
2501 | 2580 | |
---|
2502 | 2581 | list_for_each_entry_safe(priv, tmp, dev_list, list) { |
---|
2503 | 2582 | LIST_HEAD(head); |
---|
.. | .. |
---|
2545 | 2624 | */ |
---|
2546 | 2625 | BUILD_BUG_ON(IPOIB_CM_COPYBREAK > IPOIB_CM_HEAD_SIZE); |
---|
2547 | 2626 | |
---|
2548 | | - ret = ipoib_register_debugfs(); |
---|
2549 | | - if (ret) |
---|
2550 | | - return ret; |
---|
| 2627 | + ipoib_register_debugfs(); |
---|
2551 | 2628 | |
---|
2552 | 2629 | /* |
---|
2553 | 2630 | * We create a global workqueue here that is used for all flush |
---|