1 /* QLogic qedr NIC Driver 2 * Copyright (c) 2015-2017 QLogic Corporation 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and /or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 */ 32 #include <linux/pci.h> 33 #include <linux/netdevice.h> 34 #include <linux/list.h> 35 #include <linux/mutex.h> 36 #include <linux/qed/qede_rdma.h> 37 #include "qede.h" 38 39 static struct qedr_driver *qedr_drv; 40 static LIST_HEAD(qedr_dev_list); 41 static DEFINE_MUTEX(qedr_dev_list_lock); 42 43 bool qede_rdma_supported(struct qede_dev *dev) 44 { 45 return dev->dev_info.common.rdma_supported; 46 } 47 48 static void _qede_rdma_dev_add(struct qede_dev *edev) 49 { 50 if (!qedr_drv) 51 return; 52 53 /* Leftovers from previous error recovery */ 54 edev->rdma_info.exp_recovery = false; 55 edev->rdma_info.qedr_dev = qedr_drv->add(edev->cdev, edev->pdev, 56 edev->ndev); 57 } 58 59 static int qede_rdma_create_wq(struct qede_dev *edev) 60 { 61 INIT_LIST_HEAD(&edev->rdma_info.rdma_event_list); 62 kref_init(&edev->rdma_info.refcnt); 63 init_completion(&edev->rdma_info.event_comp); 64 65 edev->rdma_info.rdma_wq = create_singlethread_workqueue("rdma_wq"); 66 if (!edev->rdma_info.rdma_wq) { 67 DP_NOTICE(edev, "qedr: Could not create workqueue\n"); 68 return -ENOMEM; 69 } 70 71 return 0; 72 } 73 74 static void qede_rdma_cleanup_event(struct qede_dev *edev) 75 { 76 struct list_head *head = &edev->rdma_info.rdma_event_list; 77 struct qede_rdma_event_work *event_node; 78 79 flush_workqueue(edev->rdma_info.rdma_wq); 80 while (!list_empty(head)) { 81 event_node = list_entry(head->next, struct qede_rdma_event_work, 82 list); 83 cancel_work_sync(&event_node->work); 84 list_del(&event_node->list); 85 kfree(event_node); 86 } 87 } 88 89 static void qede_rdma_complete_event(struct kref *ref) 90 { 91 struct qede_rdma_dev *rdma_dev = 92 container_of(ref, struct qede_rdma_dev, refcnt); 93 94 /* no more events will be added after this */ 95 complete(&rdma_dev->event_comp); 96 } 97 98 static void qede_rdma_destroy_wq(struct qede_dev *edev) 99 { 100 /* Avoid race with add_event flow, make sure it finishes before 101 * we start accessing the list and cleaning up the work 102 */ 103 kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); 104 wait_for_completion(&edev->rdma_info.event_comp); 105 106 qede_rdma_cleanup_event(edev); 107 destroy_workqueue(edev->rdma_info.rdma_wq); 108 } 109 110 int qede_rdma_dev_add(struct qede_dev *edev, bool recovery) 111 { 112 int rc; 113 114 if (!qede_rdma_supported(edev)) 115 return 0; 116 117 /* Cannot start qedr while recovering since it wasn't fully stopped */ 118 if (recovery) 119 return 0; 120 121 rc = qede_rdma_create_wq(edev); 122 if (rc) 123 return rc; 124 125 INIT_LIST_HEAD(&edev->rdma_info.entry); 126 mutex_lock(&qedr_dev_list_lock); 127 list_add_tail(&edev->rdma_info.entry, &qedr_dev_list); 128 _qede_rdma_dev_add(edev); 129 mutex_unlock(&qedr_dev_list_lock); 130 131 return rc; 132 } 133 134 static void _qede_rdma_dev_remove(struct qede_dev *edev) 135 { 136 if (qedr_drv && qedr_drv->remove && edev->rdma_info.qedr_dev) 137 qedr_drv->remove(edev->rdma_info.qedr_dev); 138 } 139 140 void qede_rdma_dev_remove(struct qede_dev *edev, bool recovery) 141 { 142 if (!qede_rdma_supported(edev)) 143 return; 144 145 /* Cannot remove qedr while recovering since it wasn't fully stopped */ 146 if (!recovery) { 147 qede_rdma_destroy_wq(edev); 148 mutex_lock(&qedr_dev_list_lock); 149 if (!edev->rdma_info.exp_recovery) 150 _qede_rdma_dev_remove(edev); 151 edev->rdma_info.qedr_dev = NULL; 152 list_del(&edev->rdma_info.entry); 153 mutex_unlock(&qedr_dev_list_lock); 154 } else { 155 if (!edev->rdma_info.exp_recovery) { 156 mutex_lock(&qedr_dev_list_lock); 157 _qede_rdma_dev_remove(edev); 158 mutex_unlock(&qedr_dev_list_lock); 159 } 160 edev->rdma_info.exp_recovery = true; 161 } 162 } 163 164 static void _qede_rdma_dev_open(struct qede_dev *edev) 165 { 166 if (qedr_drv && edev->rdma_info.qedr_dev && qedr_drv->notify) 167 qedr_drv->notify(edev->rdma_info.qedr_dev, QEDE_UP); 168 } 169 170 static void qede_rdma_dev_open(struct qede_dev *edev) 171 { 172 if (!qede_rdma_supported(edev)) 173 return; 174 175 mutex_lock(&qedr_dev_list_lock); 176 _qede_rdma_dev_open(edev); 177 mutex_unlock(&qedr_dev_list_lock); 178 } 179 180 static void _qede_rdma_dev_close(struct qede_dev *edev) 181 { 182 if (qedr_drv && edev->rdma_info.qedr_dev && qedr_drv->notify) 183 qedr_drv->notify(edev->rdma_info.qedr_dev, QEDE_DOWN); 184 } 185 186 static void qede_rdma_dev_close(struct qede_dev *edev) 187 { 188 if (!qede_rdma_supported(edev)) 189 return; 190 191 mutex_lock(&qedr_dev_list_lock); 192 _qede_rdma_dev_close(edev); 193 mutex_unlock(&qedr_dev_list_lock); 194 } 195 196 static void qede_rdma_dev_shutdown(struct qede_dev *edev) 197 { 198 if (!qede_rdma_supported(edev)) 199 return; 200 201 mutex_lock(&qedr_dev_list_lock); 202 if (qedr_drv && edev->rdma_info.qedr_dev && qedr_drv->notify) 203 qedr_drv->notify(edev->rdma_info.qedr_dev, QEDE_CLOSE); 204 mutex_unlock(&qedr_dev_list_lock); 205 } 206 207 int qede_rdma_register_driver(struct qedr_driver *drv) 208 { 209 struct qede_dev *edev; 210 u8 qedr_counter = 0; 211 212 mutex_lock(&qedr_dev_list_lock); 213 if (qedr_drv) { 214 mutex_unlock(&qedr_dev_list_lock); 215 return -EINVAL; 216 } 217 qedr_drv = drv; 218 219 list_for_each_entry(edev, &qedr_dev_list, rdma_info.entry) { 220 struct net_device *ndev; 221 222 qedr_counter++; 223 _qede_rdma_dev_add(edev); 224 ndev = edev->ndev; 225 if (netif_running(ndev) && netif_oper_up(ndev)) 226 _qede_rdma_dev_open(edev); 227 } 228 mutex_unlock(&qedr_dev_list_lock); 229 230 pr_notice("qedr: discovered and registered %d RDMA funcs\n", 231 qedr_counter); 232 233 return 0; 234 } 235 EXPORT_SYMBOL(qede_rdma_register_driver); 236 237 void qede_rdma_unregister_driver(struct qedr_driver *drv) 238 { 239 struct qede_dev *edev; 240 241 mutex_lock(&qedr_dev_list_lock); 242 list_for_each_entry(edev, &qedr_dev_list, rdma_info.entry) { 243 /* If device has experienced recovery it was already removed */ 244 if (edev->rdma_info.qedr_dev && !edev->rdma_info.exp_recovery) 245 _qede_rdma_dev_remove(edev); 246 } 247 qedr_drv = NULL; 248 mutex_unlock(&qedr_dev_list_lock); 249 } 250 EXPORT_SYMBOL(qede_rdma_unregister_driver); 251 252 static void qede_rdma_changeaddr(struct qede_dev *edev) 253 { 254 if (!qede_rdma_supported(edev)) 255 return; 256 257 if (qedr_drv && edev->rdma_info.qedr_dev && qedr_drv->notify) 258 qedr_drv->notify(edev->rdma_info.qedr_dev, QEDE_CHANGE_ADDR); 259 } 260 261 static struct qede_rdma_event_work * 262 qede_rdma_get_free_event_node(struct qede_dev *edev) 263 { 264 struct qede_rdma_event_work *event_node = NULL; 265 struct list_head *list_node = NULL; 266 bool found = false; 267 268 list_for_each(list_node, &edev->rdma_info.rdma_event_list) { 269 event_node = list_entry(list_node, struct qede_rdma_event_work, 270 list); 271 if (!work_pending(&event_node->work)) { 272 found = true; 273 break; 274 } 275 } 276 277 if (!found) { 278 event_node = kzalloc(sizeof(*event_node), GFP_ATOMIC); 279 if (!event_node) { 280 DP_NOTICE(edev, 281 "qedr: Could not allocate memory for rdma work\n"); 282 return NULL; 283 } 284 list_add_tail(&event_node->list, 285 &edev->rdma_info.rdma_event_list); 286 } 287 288 return event_node; 289 } 290 291 static void qede_rdma_handle_event(struct work_struct *work) 292 { 293 struct qede_rdma_event_work *event_node; 294 enum qede_rdma_event event; 295 struct qede_dev *edev; 296 297 event_node = container_of(work, struct qede_rdma_event_work, work); 298 event = event_node->event; 299 edev = event_node->ptr; 300 301 switch (event) { 302 case QEDE_UP: 303 qede_rdma_dev_open(edev); 304 break; 305 case QEDE_DOWN: 306 qede_rdma_dev_close(edev); 307 break; 308 case QEDE_CLOSE: 309 qede_rdma_dev_shutdown(edev); 310 break; 311 case QEDE_CHANGE_ADDR: 312 qede_rdma_changeaddr(edev); 313 break; 314 default: 315 DP_NOTICE(edev, "Invalid rdma event %d", event); 316 } 317 } 318 319 static void qede_rdma_add_event(struct qede_dev *edev, 320 enum qede_rdma_event event) 321 { 322 struct qede_rdma_event_work *event_node; 323 324 /* If a recovery was experienced avoid adding the event */ 325 if (edev->rdma_info.exp_recovery) 326 return; 327 328 if (!edev->rdma_info.qedr_dev) 329 return; 330 331 /* We don't want the cleanup flow to start while we're allocating and 332 * scheduling the work 333 */ 334 if (!kref_get_unless_zero(&edev->rdma_info.refcnt)) 335 return; /* already being destroyed */ 336 337 event_node = qede_rdma_get_free_event_node(edev); 338 if (!event_node) 339 goto out; 340 341 event_node->event = event; 342 event_node->ptr = edev; 343 344 INIT_WORK(&event_node->work, qede_rdma_handle_event); 345 queue_work(edev->rdma_info.rdma_wq, &event_node->work); 346 347 out: 348 kref_put(&edev->rdma_info.refcnt, qede_rdma_complete_event); 349 } 350 351 void qede_rdma_dev_event_open(struct qede_dev *edev) 352 { 353 qede_rdma_add_event(edev, QEDE_UP); 354 } 355 356 void qede_rdma_dev_event_close(struct qede_dev *edev) 357 { 358 qede_rdma_add_event(edev, QEDE_DOWN); 359 } 360 361 void qede_rdma_event_changeaddr(struct qede_dev *edev) 362 { 363 qede_rdma_add_event(edev, QEDE_CHANGE_ADDR); 364 } 365