1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
2/* Copyright (c) 2015 - 2021 Intel Corporation */
3#include "main.h"
4#include <linux/net/intel/iidc_rdma_idpf.h>
5
6MODULE_ALIAS("i40iw");
7MODULE_DESCRIPTION("Intel(R) Ethernet Protocol Driver for RDMA");
8MODULE_LICENSE("Dual BSD/GPL");
9
10static struct notifier_block irdma_inetaddr_notifier = {
11 .notifier_call = irdma_inetaddr_event
12};
13
14static struct notifier_block irdma_inetaddr6_notifier = {
15 .notifier_call = irdma_inet6addr_event
16};
17
18static struct notifier_block irdma_net_notifier = {
19 .notifier_call = irdma_net_event
20};
21
22static struct notifier_block irdma_netdevice_notifier = {
23 .notifier_call = irdma_netdevice_event
24};
25
26static void irdma_register_notifiers(void)
27{
28 register_inetaddr_notifier(nb: &irdma_inetaddr_notifier);
29 register_inet6addr_notifier(nb: &irdma_inetaddr6_notifier);
30 register_netevent_notifier(nb: &irdma_net_notifier);
31 register_netdevice_notifier(nb: &irdma_netdevice_notifier);
32}
33
34static void irdma_unregister_notifiers(void)
35{
36 unregister_netevent_notifier(nb: &irdma_net_notifier);
37 unregister_inetaddr_notifier(nb: &irdma_inetaddr_notifier);
38 unregister_inet6addr_notifier(nb: &irdma_inetaddr6_notifier);
39 unregister_netdevice_notifier(nb: &irdma_netdevice_notifier);
40}
41
42void irdma_log_invalid_mtu(u16 mtu, struct irdma_sc_dev *dev)
43{
44 if (mtu < IRDMA_MIN_MTU_IPV4)
45 ibdev_warn(ibdev: to_ibdev(dev), format: "MTU setting [%d] too low for RDMA traffic. Minimum MTU is 576 for IPv4\n", mtu);
46 else if (mtu < IRDMA_MIN_MTU_IPV6)
47 ibdev_warn(ibdev: to_ibdev(dev), format: "MTU setting [%d] too low for RDMA traffic. Minimum MTU is 1280 for IPv6\\n", mtu);
48}
49
50static void ig3rdma_idc_vport_event_handler(struct iidc_rdma_vport_dev_info *cdev_info,
51 struct iidc_rdma_event *event)
52{
53 struct irdma_device *iwdev = auxiliary_get_drvdata(auxdev: cdev_info->adev);
54 struct irdma_l2params l2params = {};
55
56 if (*event->type & BIT(IIDC_RDMA_EVENT_AFTER_MTU_CHANGE)) {
57 ibdev_dbg(&iwdev->ibdev, "CLNT: new MTU = %d\n", iwdev->netdev->mtu);
58 if (iwdev->vsi.mtu != iwdev->netdev->mtu) {
59 l2params.mtu = iwdev->netdev->mtu;
60 l2params.mtu_changed = true;
61 irdma_log_invalid_mtu(mtu: l2params.mtu, dev: &iwdev->rf->sc_dev);
62 irdma_change_l2params(vsi: &iwdev->vsi, l2params: &l2params);
63 }
64 }
65}
66
67static int ig3rdma_vport_probe(struct auxiliary_device *aux_dev,
68 const struct auxiliary_device_id *id)
69{
70 struct iidc_rdma_vport_auxiliary_dev *idc_adev =
71 container_of(aux_dev, struct iidc_rdma_vport_auxiliary_dev, adev);
72 struct auxiliary_device *aux_core_dev = idc_adev->vdev_info->core_adev;
73 struct irdma_pci_f *rf = auxiliary_get_drvdata(auxdev: aux_core_dev);
74 struct irdma_l2params l2params = {};
75 struct irdma_device *iwdev;
76 int err;
77
78 if (!rf) {
79 WARN_ON_ONCE(1);
80 return -ENOMEM;
81 }
82 iwdev = ib_alloc_device(irdma_device, ibdev);
83 /* Fill iwdev info */
84 iwdev->is_vport = true;
85 iwdev->rf = rf;
86 iwdev->vport_id = idc_adev->vdev_info->vport_id;
87 iwdev->netdev = idc_adev->vdev_info->netdev;
88 iwdev->init_state = INITIAL_STATE;
89 iwdev->roce_cwnd = IRDMA_ROCE_CWND_DEFAULT;
90 iwdev->roce_ackcreds = IRDMA_ROCE_ACKCREDS_DEFAULT;
91 iwdev->rcv_wnd = IRDMA_CM_DEFAULT_RCV_WND_SCALED;
92 iwdev->rcv_wscale = IRDMA_CM_DEFAULT_RCV_WND_SCALE;
93 iwdev->roce_mode = true;
94 iwdev->push_mode = false;
95
96 l2params.mtu = iwdev->netdev->mtu;
97
98 err = irdma_rt_init_hw(iwdev, l2params: &l2params);
99 if (err)
100 goto err_rt_init;
101
102 err = irdma_ib_register_device(iwdev);
103 if (err)
104 goto err_ibreg;
105
106 auxiliary_set_drvdata(auxdev: aux_dev, data: iwdev);
107
108 ibdev_dbg(&iwdev->ibdev,
109 "INIT: Gen[%d] vport[%d] probe success. dev_name = %s, core_dev_name = %s, netdev=%s\n",
110 rf->rdma_ver, idc_adev->vdev_info->vport_id,
111 dev_name(&aux_dev->dev),
112 dev_name(&idc_adev->vdev_info->core_adev->dev),
113 netdev_name(idc_adev->vdev_info->netdev));
114
115 return 0;
116err_ibreg:
117 irdma_rt_deinit_hw(iwdev);
118err_rt_init:
119 ib_dealloc_device(device: &iwdev->ibdev);
120
121 return err;
122}
123
124static void ig3rdma_vport_remove(struct auxiliary_device *aux_dev)
125{
126 struct iidc_rdma_vport_auxiliary_dev *idc_adev =
127 container_of(aux_dev, struct iidc_rdma_vport_auxiliary_dev, adev);
128 struct irdma_device *iwdev = auxiliary_get_drvdata(auxdev: aux_dev);
129
130 ibdev_dbg(&iwdev->ibdev,
131 "INIT: Gen[%d] dev_name = %s, core_dev_name = %s, netdev=%s\n",
132 iwdev->rf->rdma_ver, dev_name(&aux_dev->dev),
133 dev_name(&idc_adev->vdev_info->core_adev->dev),
134 netdev_name(idc_adev->vdev_info->netdev));
135
136 irdma_ib_unregister_device(iwdev);
137}
138
139static const struct auxiliary_device_id ig3rdma_vport_auxiliary_id_table[] = {
140 {.name = "idpf.8086.rdma.vdev", },
141 {},
142};
143
144MODULE_DEVICE_TABLE(auxiliary, ig3rdma_vport_auxiliary_id_table);
145
146static struct iidc_rdma_vport_auxiliary_drv ig3rdma_vport_auxiliary_drv = {
147 .adrv = {
148 .name = "vdev",
149 .id_table = ig3rdma_vport_auxiliary_id_table,
150 .probe = ig3rdma_vport_probe,
151 .remove = ig3rdma_vport_remove,
152 },
153 .event_handler = ig3rdma_idc_vport_event_handler,
154};
155
156
157static int __init irdma_init_module(void)
158{
159 int ret;
160
161 ret = auxiliary_driver_register(&i40iw_auxiliary_drv);
162 if (ret) {
163 pr_err("Failed i40iw(gen_1) auxiliary_driver_register() ret=%d\n",
164 ret);
165 return ret;
166 }
167
168 ret = auxiliary_driver_register(&icrdma_core_auxiliary_drv.adrv);
169 if (ret) {
170 auxiliary_driver_unregister(auxdrv: &i40iw_auxiliary_drv);
171 pr_err("Failed icrdma(gen_2) auxiliary_driver_register() ret=%d\n",
172 ret);
173 return ret;
174 }
175
176 ret = auxiliary_driver_register(&ig3rdma_core_auxiliary_drv.adrv);
177 if (ret) {
178 auxiliary_driver_unregister(auxdrv: &icrdma_core_auxiliary_drv.adrv);
179 auxiliary_driver_unregister(auxdrv: &i40iw_auxiliary_drv);
180 pr_err("Failed ig3rdma(gen_3) core auxiliary_driver_register() ret=%d\n",
181 ret);
182
183 return ret;
184 }
185
186 ret = auxiliary_driver_register(&ig3rdma_vport_auxiliary_drv.adrv);
187 if (ret) {
188 auxiliary_driver_unregister(auxdrv: &ig3rdma_core_auxiliary_drv.adrv);
189 auxiliary_driver_unregister(auxdrv: &icrdma_core_auxiliary_drv.adrv);
190 auxiliary_driver_unregister(auxdrv: &i40iw_auxiliary_drv);
191 pr_err("Failed ig3rdma vport auxiliary_driver_register() ret=%d\n",
192 ret);
193
194 return ret;
195 }
196 irdma_register_notifiers();
197
198 return 0;
199}
200
201static void __exit irdma_exit_module(void)
202{
203 irdma_unregister_notifiers();
204 auxiliary_driver_unregister(auxdrv: &icrdma_core_auxiliary_drv.adrv);
205 auxiliary_driver_unregister(auxdrv: &i40iw_auxiliary_drv);
206 auxiliary_driver_unregister(auxdrv: &ig3rdma_core_auxiliary_drv.adrv);
207 auxiliary_driver_unregister(auxdrv: &ig3rdma_vport_auxiliary_drv.adrv);
208}
209
210module_init(irdma_init_module);
211module_exit(irdma_exit_module);
212

source code of linux/drivers/infiniband/hw/irdma/main.c