.. | .. |
---|
51 | 51 | */ |
---|
52 | 52 | |
---|
53 | 53 | #include <linux/module.h> |
---|
| 54 | +#include <linux/xarray.h> |
---|
54 | 55 | #include <rdma/ib_addr.h> |
---|
55 | 56 | #include <rdma/ib_verbs.h> |
---|
56 | 57 | #include <rdma/opa_smi.h> |
---|
.. | .. |
---|
58 | 59 | |
---|
59 | 60 | #include "opa_vnic_internal.h" |
---|
60 | 61 | |
---|
61 | | -#define DRV_VERSION "1.0" |
---|
62 | 62 | char opa_vnic_driver_name[] = "opa_vnic"; |
---|
63 | | -const char opa_vnic_driver_version[] = DRV_VERSION; |
---|
64 | 63 | |
---|
65 | 64 | /* |
---|
66 | 65 | * The trap service level is kept in bits 3 to 7 in the trap_sl_rsvd |
---|
.. | .. |
---|
97 | 96 | * @class_port_info: Class port info information. |
---|
98 | 97 | * @tid: Transaction id |
---|
99 | 98 | * @port_num: OPA port number |
---|
100 | | - * @vport_idr: vnic ports idr |
---|
| 99 | + * @vports: vnic ports |
---|
101 | 100 | * @event_handler: ib event handler |
---|
102 | 101 | * @lock: adapter interface lock |
---|
103 | 102 | */ |
---|
.. | .. |
---|
107 | 106 | struct opa_class_port_info class_port_info; |
---|
108 | 107 | u64 tid; |
---|
109 | 108 | u8 port_num; |
---|
110 | | - struct idr vport_idr; |
---|
| 109 | + struct xarray vports; |
---|
111 | 110 | struct ib_event_handler event_handler; |
---|
112 | 111 | |
---|
113 | 112 | /* Lock to query/update network adapter */ |
---|
114 | 113 | struct mutex lock; |
---|
115 | 114 | }; |
---|
116 | 115 | |
---|
117 | | -static void opa_vnic_vema_add_one(struct ib_device *device); |
---|
| 116 | +static int opa_vnic_vema_add_one(struct ib_device *device); |
---|
118 | 117 | static void opa_vnic_vema_rem_one(struct ib_device *device, |
---|
119 | 118 | void *client_data); |
---|
120 | 119 | |
---|
.. | .. |
---|
148 | 147 | { |
---|
149 | 148 | u8 vport_num = vema_get_vport_num(recvd_mad); |
---|
150 | 149 | |
---|
151 | | - return idr_find(&port->vport_idr, vport_num); |
---|
| 150 | + return xa_load(&port->vports, vport_num); |
---|
152 | 151 | } |
---|
153 | 152 | |
---|
154 | 153 | /** |
---|
.. | .. |
---|
207 | 206 | int rc; |
---|
208 | 207 | |
---|
209 | 208 | adapter->cport = cport; |
---|
210 | | - rc = idr_alloc(&port->vport_idr, adapter, vport_num, |
---|
211 | | - vport_num + 1, GFP_NOWAIT); |
---|
| 209 | + rc = xa_insert(&port->vports, vport_num, adapter, GFP_KERNEL); |
---|
212 | 210 | if (rc < 0) { |
---|
213 | 211 | opa_vnic_rem_netdev(adapter); |
---|
214 | 212 | adapter = ERR_PTR(rc); |
---|
.. | .. |
---|
549 | 547 | vema_get_mac_entries(port, recvd_mad, rsp_mad); |
---|
550 | 548 | break; |
---|
551 | 549 | case OPA_EM_ATTR_IFACE_UCAST_MACS: |
---|
552 | | - /* fall through */ |
---|
553 | 550 | case OPA_EM_ATTR_IFACE_MCAST_MACS: |
---|
554 | 551 | vema_get_mac_list(port, recvd_mad, rsp_mad, attr_id); |
---|
555 | 552 | break; |
---|
.. | .. |
---|
606 | 603 | static void vema_send(struct ib_mad_agent *mad_agent, |
---|
607 | 604 | struct ib_mad_send_wc *mad_wc) |
---|
608 | 605 | { |
---|
609 | | - rdma_destroy_ah(mad_wc->send_buf->ah); |
---|
| 606 | + rdma_destroy_ah(mad_wc->send_buf->ah, RDMA_DESTROY_AH_SLEEPABLE); |
---|
610 | 607 | ib_free_send_mad(mad_wc->send_buf); |
---|
611 | 608 | } |
---|
612 | 609 | |
---|
.. | .. |
---|
680 | 677 | ib_free_send_mad(rsp); |
---|
681 | 678 | |
---|
682 | 679 | err_rsp: |
---|
683 | | - rdma_destroy_ah(ah); |
---|
| 680 | + rdma_destroy_ah(ah, RDMA_DESTROY_AH_SLEEPABLE); |
---|
684 | 681 | free_recv_mad: |
---|
685 | 682 | ib_free_recv_mad(mad_wc); |
---|
686 | 683 | } |
---|
.. | .. |
---|
777 | 774 | } |
---|
778 | 775 | |
---|
779 | 776 | rdma_ah_set_dlid(&ah_attr, trap_lid); |
---|
780 | | - ah = rdma_create_ah(port->mad_agent->qp->pd, &ah_attr); |
---|
| 777 | + ah = rdma_create_ah(port->mad_agent->qp->pd, &ah_attr, 0); |
---|
781 | 778 | if (IS_ERR(ah)) { |
---|
782 | 779 | c_err("%s:Couldn't create new AH = %p\n", __func__, ah); |
---|
783 | 780 | c_err("%s:dlid = %d, sl = %d, port = %d\n", __func__, |
---|
.. | .. |
---|
848 | 845 | } |
---|
849 | 846 | |
---|
850 | 847 | err_sndbuf: |
---|
851 | | - rdma_destroy_ah(ah); |
---|
| 848 | + rdma_destroy_ah(ah, 0); |
---|
852 | 849 | err_exit: |
---|
853 | 850 | v_err("Aborting trap\n"); |
---|
854 | | -} |
---|
855 | | - |
---|
856 | | -static int vema_rem_vport(int id, void *p, void *data) |
---|
857 | | -{ |
---|
858 | | - struct opa_vnic_adapter *adapter = p; |
---|
859 | | - |
---|
860 | | - opa_vnic_rem_netdev(adapter); |
---|
861 | | - return 0; |
---|
862 | | -} |
---|
863 | | - |
---|
864 | | -static int vema_enable_vport(int id, void *p, void *data) |
---|
865 | | -{ |
---|
866 | | - struct opa_vnic_adapter *adapter = p; |
---|
867 | | - |
---|
868 | | - netif_carrier_on(adapter->netdev); |
---|
869 | | - return 0; |
---|
870 | | -} |
---|
871 | | - |
---|
872 | | -static int vema_disable_vport(int id, void *p, void *data) |
---|
873 | | -{ |
---|
874 | | - struct opa_vnic_adapter *adapter = p; |
---|
875 | | - |
---|
876 | | - netif_carrier_off(adapter->netdev); |
---|
877 | | - return 0; |
---|
878 | 851 | } |
---|
879 | 852 | |
---|
880 | 853 | static void opa_vnic_event(struct ib_event_handler *handler, |
---|
.. | .. |
---|
883 | 856 | struct opa_vnic_vema_port *port = |
---|
884 | 857 | container_of(handler, struct opa_vnic_vema_port, event_handler); |
---|
885 | 858 | struct opa_vnic_ctrl_port *cport = port->cport; |
---|
| 859 | + struct opa_vnic_adapter *adapter; |
---|
| 860 | + unsigned long index; |
---|
886 | 861 | |
---|
887 | 862 | if (record->element.port_num != port->port_num) |
---|
888 | 863 | return; |
---|
889 | 864 | |
---|
890 | 865 | c_dbg("OPA_VNIC received event %d on device %s port %d\n", |
---|
891 | | - record->event, record->device->name, record->element.port_num); |
---|
| 866 | + record->event, dev_name(&record->device->dev), |
---|
| 867 | + record->element.port_num); |
---|
892 | 868 | |
---|
893 | | - if (record->event == IB_EVENT_PORT_ERR) |
---|
894 | | - idr_for_each(&port->vport_idr, vema_disable_vport, NULL); |
---|
895 | | - if (record->event == IB_EVENT_PORT_ACTIVE) |
---|
896 | | - idr_for_each(&port->vport_idr, vema_enable_vport, NULL); |
---|
| 869 | + if (record->event != IB_EVENT_PORT_ERR && |
---|
| 870 | + record->event != IB_EVENT_PORT_ACTIVE) |
---|
| 871 | + return; |
---|
| 872 | + |
---|
| 873 | + xa_for_each(&port->vports, index, adapter) { |
---|
| 874 | + if (record->event == IB_EVENT_PORT_ACTIVE) |
---|
| 875 | + netif_carrier_on(adapter->netdev); |
---|
| 876 | + else |
---|
| 877 | + netif_carrier_off(adapter->netdev); |
---|
| 878 | + } |
---|
897 | 879 | } |
---|
898 | 880 | |
---|
899 | 881 | /** |
---|
.. | .. |
---|
904 | 886 | */ |
---|
905 | 887 | static void vema_unregister(struct opa_vnic_ctrl_port *cport) |
---|
906 | 888 | { |
---|
| 889 | + struct opa_vnic_adapter *adapter; |
---|
| 890 | + unsigned long index; |
---|
907 | 891 | int i; |
---|
908 | 892 | |
---|
909 | 893 | for (i = 1; i <= cport->num_ports; i++) { |
---|
.. | .. |
---|
914 | 898 | |
---|
915 | 899 | /* Lock ensures no MAD is being processed */ |
---|
916 | 900 | mutex_lock(&port->lock); |
---|
917 | | - idr_for_each(&port->vport_idr, vema_rem_vport, NULL); |
---|
| 901 | + xa_for_each(&port->vports, index, adapter) |
---|
| 902 | + opa_vnic_rem_netdev(adapter); |
---|
918 | 903 | mutex_unlock(&port->lock); |
---|
919 | 904 | |
---|
920 | 905 | ib_unregister_mad_agent(port->mad_agent); |
---|
921 | 906 | port->mad_agent = NULL; |
---|
922 | 907 | mutex_destroy(&port->lock); |
---|
923 | | - idr_destroy(&port->vport_idr); |
---|
| 908 | + xa_destroy(&port->vports); |
---|
924 | 909 | ib_unregister_event_handler(&port->event_handler); |
---|
925 | 910 | } |
---|
926 | 911 | } |
---|
.. | .. |
---|
957 | 942 | cport->ibdev, opa_vnic_event); |
---|
958 | 943 | ib_register_event_handler(&port->event_handler); |
---|
959 | 944 | |
---|
960 | | - idr_init(&port->vport_idr); |
---|
| 945 | + xa_init(&port->vports); |
---|
961 | 946 | mutex_init(&port->lock); |
---|
962 | 947 | port->mad_agent = ib_register_mad_agent(cport->ibdev, i, |
---|
963 | 948 | IB_QPT_GSI, ®_req, |
---|
.. | .. |
---|
968 | 953 | ret = PTR_ERR(port->mad_agent); |
---|
969 | 954 | port->mad_agent = NULL; |
---|
970 | 955 | mutex_destroy(&port->lock); |
---|
971 | | - idr_destroy(&port->vport_idr); |
---|
972 | 956 | vema_unregister(cport); |
---|
973 | 957 | return ret; |
---|
974 | 958 | } |
---|
.. | .. |
---|
1004 | 988 | * |
---|
1005 | 989 | * Allocate the vnic control port and initialize it. |
---|
1006 | 990 | */ |
---|
1007 | | -static void opa_vnic_vema_add_one(struct ib_device *device) |
---|
| 991 | +static int opa_vnic_vema_add_one(struct ib_device *device) |
---|
1008 | 992 | { |
---|
1009 | 993 | struct opa_vnic_ctrl_port *cport; |
---|
1010 | 994 | int rc, size = sizeof(*cport); |
---|
1011 | 995 | |
---|
1012 | 996 | if (!rdma_cap_opa_vnic(device)) |
---|
1013 | | - return; |
---|
| 997 | + return -EOPNOTSUPP; |
---|
1014 | 998 | |
---|
1015 | 999 | size += device->phys_port_cnt * sizeof(struct opa_vnic_vema_port); |
---|
1016 | 1000 | cport = kzalloc(size, GFP_KERNEL); |
---|
1017 | 1001 | if (!cport) |
---|
1018 | | - return; |
---|
| 1002 | + return -ENOMEM; |
---|
1019 | 1003 | |
---|
1020 | 1004 | cport->num_ports = device->phys_port_cnt; |
---|
1021 | 1005 | cport->ibdev = device; |
---|
.. | .. |
---|
1027 | 1011 | |
---|
1028 | 1012 | ib_set_client_data(device, &opa_vnic_client, cport); |
---|
1029 | 1013 | opa_vnic_ctrl_config_dev(cport, true); |
---|
| 1014 | + return 0; |
---|
1030 | 1015 | } |
---|
1031 | 1016 | |
---|
1032 | 1017 | /** |
---|
.. | .. |
---|
1041 | 1026 | { |
---|
1042 | 1027 | struct opa_vnic_ctrl_port *cport = client_data; |
---|
1043 | 1028 | |
---|
1044 | | - if (!cport) |
---|
1045 | | - return; |
---|
1046 | | - |
---|
1047 | 1029 | c_info("removing VNIC client\n"); |
---|
1048 | 1030 | opa_vnic_ctrl_config_dev(cport, false); |
---|
1049 | 1031 | vema_unregister(cport); |
---|
.. | .. |
---|
1053 | 1035 | static int __init opa_vnic_init(void) |
---|
1054 | 1036 | { |
---|
1055 | 1037 | int rc; |
---|
1056 | | - |
---|
1057 | | - pr_info("OPA Virtual Network Driver - v%s\n", |
---|
1058 | | - opa_vnic_driver_version); |
---|
1059 | 1038 | |
---|
1060 | 1039 | rc = ib_register_client(&opa_vnic_client); |
---|
1061 | 1040 | if (rc) |
---|