a0135297b1c6c17df8a569fbd160abc99d9444af
[firefly-linux-kernel-4.4.55.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_sriov_pf.c
1 /*
2  * QLogic qlcnic NIC Driver
3  * Copyright (c) 2009-2013 QLogic Corporation
4  *
5  * See LICENSE.qlcnic for copyright and licensing details.
6  */
7
8 #include "qlcnic_sriov.h"
9 #include "qlcnic.h"
10 #include <linux/types.h>
11
12 #define QLCNIC_SRIOV_VF_MAX_MAC 1
13
14 static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8);
15
16 struct qlcnic_sriov_cmd_handler {
17         int (*fn) (struct qlcnic_bc_trans *, struct qlcnic_cmd_args *);
18 };
19
20 struct qlcnic_sriov_fw_cmd_handler {
21         u32 cmd;
22         int (*fn) (struct qlcnic_bc_trans *, struct qlcnic_cmd_args *);
23 };
24
25 static int qlcnic_sriov_pf_set_vport_info(struct qlcnic_adapter *adapter,
26                                           struct qlcnic_info *npar_info,
27                                           u16 vport_id)
28 {
29         struct qlcnic_cmd_args cmd;
30         int err;
31
32         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_SET_NIC_INFO))
33                 return -ENOMEM;
34
35         cmd.req.arg[1] = (vport_id << 16) | 0x1;
36         cmd.req.arg[2] = npar_info->bit_offsets;
37         cmd.req.arg[2] |= npar_info->min_tx_bw << 16;
38         cmd.req.arg[3] = npar_info->max_tx_bw | (npar_info->max_tx_ques << 16);
39         cmd.req.arg[4] = npar_info->max_tx_mac_filters;
40         cmd.req.arg[4] |= npar_info->max_rx_mcast_mac_filters << 16;
41         cmd.req.arg[5] = npar_info->max_rx_ucast_mac_filters |
42                          (npar_info->max_rx_ip_addr << 16);
43         cmd.req.arg[6] = npar_info->max_rx_lro_flow |
44                          (npar_info->max_rx_status_rings << 16);
45         cmd.req.arg[7] = npar_info->max_rx_buf_rings |
46                          (npar_info->max_rx_ques << 16);
47         cmd.req.arg[8] = npar_info->max_tx_vlan_keys;
48         cmd.req.arg[8] |= npar_info->max_local_ipv6_addrs << 16;
49         cmd.req.arg[9] = npar_info->max_remote_ipv6_addrs;
50
51         err = qlcnic_issue_cmd(adapter, &cmd);
52         if (err)
53                 dev_err(&adapter->pdev->dev,
54                         "Failed to set vport info, err=%d\n", err);
55
56         qlcnic_free_mbx_args(&cmd);
57         return err;
58 }
59
60 static int qlcnic_sriov_pf_cal_res_limit(struct qlcnic_adapter *adapter,
61                                          struct qlcnic_info *info, u16 func)
62 {
63         struct qlcnic_sriov *sriov = adapter->ahw->sriov;
64         struct qlcnic_resources *res = &sriov->ff_max;
65         int ret = -EIO, vpid;
66         u32 temp, num_vf_macs, num_vfs, max;
67
68         vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func);
69         if (vpid < 0)
70                 return -EINVAL;
71
72         num_vfs = sriov->num_vfs;
73         max = num_vfs + 1;
74         info->bit_offsets = 0xffff;
75         info->min_tx_bw = 0;
76         info->max_tx_bw = MAX_BW;
77         info->max_tx_ques = res->num_tx_queues / max;
78         info->max_rx_mcast_mac_filters = res->num_rx_mcast_mac_filters;
79         num_vf_macs = QLCNIC_SRIOV_VF_MAX_MAC;
80
81         if (adapter->ahw->pci_func == func) {
82                 temp = res->num_rx_mcast_mac_filters - (num_vfs * num_vf_macs);
83                 info->max_rx_ucast_mac_filters = temp;
84                 temp = res->num_tx_mac_filters - (num_vfs * num_vf_macs);
85                 info->max_tx_mac_filters = temp;
86         } else {
87                 info->max_rx_ucast_mac_filters = num_vf_macs;
88                 info->max_tx_mac_filters = num_vf_macs;
89         }
90
91         info->max_rx_ip_addr = res->num_destip / max;
92         info->max_rx_status_rings = res->num_rx_status_rings / max;
93         info->max_rx_buf_rings = res->num_rx_buf_rings / max;
94         info->max_rx_ques = res->num_rx_queues / max;
95         info->max_rx_lro_flow = res->num_lro_flows_supported / max;
96         info->max_tx_vlan_keys = res->num_txvlan_keys;
97         info->max_local_ipv6_addrs = res->max_local_ipv6_addrs;
98         info->max_remote_ipv6_addrs = res->max_remote_ipv6_addrs;
99
100         ret = qlcnic_sriov_pf_set_vport_info(adapter, info, vpid);
101         if (ret)
102                 return ret;
103
104         return 0;
105 }
106
107 static void qlcnic_sriov_pf_set_ff_max_res(struct qlcnic_adapter *adapter,
108                                            struct qlcnic_info *info)
109 {
110         struct qlcnic_resources *ff_max = &adapter->ahw->sriov->ff_max;
111
112         ff_max->num_tx_mac_filters = info->max_tx_mac_filters;
113         ff_max->num_rx_ucast_mac_filters = info->max_rx_ucast_mac_filters;
114         ff_max->num_rx_mcast_mac_filters = info->max_rx_mcast_mac_filters;
115         ff_max->num_txvlan_keys = info->max_tx_vlan_keys;
116         ff_max->num_rx_queues = info->max_rx_ques;
117         ff_max->num_tx_queues = info->max_tx_ques;
118         ff_max->num_lro_flows_supported = info->max_rx_lro_flow;
119         ff_max->num_destip = info->max_rx_ip_addr;
120         ff_max->num_rx_buf_rings = info->max_rx_buf_rings;
121         ff_max->num_rx_status_rings = info->max_rx_status_rings;
122         ff_max->max_remote_ipv6_addrs = info->max_remote_ipv6_addrs;
123         ff_max->max_local_ipv6_addrs = info->max_local_ipv6_addrs;
124 }
125
126 static int qlcnic_sriov_get_pf_info(struct qlcnic_adapter *adapter,
127                                     struct qlcnic_info *npar_info)
128 {
129         int err;
130         struct qlcnic_cmd_args cmd;
131
132         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_GET_NIC_INFO))
133                 return -ENOMEM;
134
135         cmd.req.arg[1] = 0x2;
136         err = qlcnic_issue_cmd(adapter, &cmd);
137         if (err) {
138                 dev_err(&adapter->pdev->dev,
139                         "Failed to get PF info, err=%d\n", err);
140                 goto out;
141         }
142
143         npar_info->total_pf = cmd.rsp.arg[2] & 0xff;
144         npar_info->total_rss_engines = (cmd.rsp.arg[2] >> 8) & 0xff;
145         npar_info->max_vports = MSW(cmd.rsp.arg[2]);
146         npar_info->max_tx_ques =  LSW(cmd.rsp.arg[3]);
147         npar_info->max_tx_mac_filters = MSW(cmd.rsp.arg[3]);
148         npar_info->max_rx_mcast_mac_filters = LSW(cmd.rsp.arg[4]);
149         npar_info->max_rx_ucast_mac_filters = MSW(cmd.rsp.arg[4]);
150         npar_info->max_rx_ip_addr = LSW(cmd.rsp.arg[5]);
151         npar_info->max_rx_lro_flow = MSW(cmd.rsp.arg[5]);
152         npar_info->max_rx_status_rings = LSW(cmd.rsp.arg[6]);
153         npar_info->max_rx_buf_rings = MSW(cmd.rsp.arg[6]);
154         npar_info->max_rx_ques = LSW(cmd.rsp.arg[7]);
155         npar_info->max_tx_vlan_keys = MSW(cmd.rsp.arg[7]);
156         npar_info->max_local_ipv6_addrs = LSW(cmd.rsp.arg[8]);
157         npar_info->max_remote_ipv6_addrs = MSW(cmd.rsp.arg[8]);
158
159         qlcnic_sriov_pf_set_ff_max_res(adapter, npar_info);
160         dev_info(&adapter->pdev->dev,
161                  "\n\ttotal_pf: %d,\n"
162                  "\n\ttotal_rss_engines: %d max_vports: %d max_tx_ques %d,\n"
163                  "\tmax_tx_mac_filters: %d max_rx_mcast_mac_filters: %d,\n"
164                  "\tmax_rx_ucast_mac_filters: 0x%x, max_rx_ip_addr: %d,\n"
165                  "\tmax_rx_lro_flow: %d max_rx_status_rings: %d,\n"
166                  "\tmax_rx_buf_rings: %d, max_rx_ques: %d, max_tx_vlan_keys %d\n"
167                  "\tmax_local_ipv6_addrs: %d, max_remote_ipv6_addrs: %d\n",
168                  npar_info->total_pf, npar_info->total_rss_engines,
169                  npar_info->max_vports, npar_info->max_tx_ques,
170                  npar_info->max_tx_mac_filters,
171                  npar_info->max_rx_mcast_mac_filters,
172                  npar_info->max_rx_ucast_mac_filters, npar_info->max_rx_ip_addr,
173                  npar_info->max_rx_lro_flow, npar_info->max_rx_status_rings,
174                  npar_info->max_rx_buf_rings, npar_info->max_rx_ques,
175                  npar_info->max_tx_vlan_keys, npar_info->max_local_ipv6_addrs,
176                  npar_info->max_remote_ipv6_addrs);
177
178 out:
179         qlcnic_free_mbx_args(&cmd);
180         return err;
181 }
182
183 static void qlcnic_sriov_pf_reset_vport_handle(struct qlcnic_adapter *adapter,
184                                                u8 func)
185 {
186         struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
187         struct qlcnic_vport *vp;
188         int index;
189
190         if (adapter->ahw->pci_func == func) {
191                 sriov->vp_handle = 0;
192         } else {
193                 index = qlcnic_sriov_func_to_index(adapter, func);
194                 if (index < 0)
195                         return;
196                 vp = sriov->vf_info[index].vp;
197                 vp->handle = 0;
198         }
199 }
200
201 static void qlcnic_sriov_pf_set_vport_handle(struct qlcnic_adapter *adapter,
202                                              u16 vport_handle, u8 func)
203 {
204         struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
205         struct qlcnic_vport *vp;
206         int index;
207
208         if (adapter->ahw->pci_func == func) {
209                 sriov->vp_handle = vport_handle;
210         } else {
211                 index = qlcnic_sriov_func_to_index(adapter, func);
212                 if (index < 0)
213                         return;
214                 vp = sriov->vf_info[index].vp;
215                 vp->handle = vport_handle;
216         }
217 }
218
219 static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *adapter,
220                                             u8 func)
221 {
222         struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
223         struct qlcnic_vf_info *vf_info;
224         int index;
225
226         if (adapter->ahw->pci_func == func) {
227                 return sriov->vp_handle;
228         } else {
229                 index = qlcnic_sriov_func_to_index(adapter, func);
230                 if (index >= 0) {
231                         vf_info = &sriov->vf_info[index];
232                         return vf_info->vp->handle;
233                 }
234         }
235
236         return -EINVAL;
237 }
238
239 static int qlcnic_sriov_pf_config_vport(struct qlcnic_adapter *adapter,
240                                         u8 flag, u16 func)
241 {
242         struct qlcnic_cmd_args cmd;
243         int ret;
244         int vpid;
245
246         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_VPORT))
247                 return -ENOMEM;
248
249         if (flag) {
250                 cmd.req.arg[3] = func << 8;
251         } else {
252                 vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func);
253                 if (vpid < 0) {
254                         ret = -EINVAL;
255                         goto out;
256                 }
257                 cmd.req.arg[3] = ((vpid & 0xffff) << 8) | 1;
258         }
259
260         ret = qlcnic_issue_cmd(adapter, &cmd);
261         if (ret) {
262                 dev_err(&adapter->pdev->dev,
263                         "Failed %s vport, err %d for func 0x%x\n",
264                         (flag ? "enable" : "disable"), ret, func);
265                 goto out;
266         }
267
268         if (flag) {
269                 vpid = cmd.rsp.arg[2] & 0xffff;
270                 qlcnic_sriov_pf_set_vport_handle(adapter, vpid, func);
271         } else {
272                 qlcnic_sriov_pf_reset_vport_handle(adapter, func);
273         }
274
275 out:
276         qlcnic_free_mbx_args(&cmd);
277         return ret;
278 }
279
280 static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter,
281                                        u8 func, u8 enable)
282 {
283         struct qlcnic_cmd_args cmd;
284         int err = -EIO;
285
286         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH))
287                 return -ENOMEM;
288
289         cmd.req.arg[0] |= (3 << 29);
290         cmd.req.arg[1] = ((func & 0xf) << 2) | BIT_6 | BIT_1;
291         if (enable)
292                 cmd.req.arg[1] |= BIT_0;
293
294         err = qlcnic_issue_cmd(adapter, &cmd);
295
296         if (err != QLCNIC_RCODE_SUCCESS) {
297                 dev_err(&adapter->pdev->dev,
298                         "Failed to enable sriov eswitch%d\n", err);
299                 err = -EIO;
300         }
301
302         qlcnic_free_mbx_args(&cmd);
303         return err;
304 }
305
306 static void qlcnic_sriov_pf_del_flr_queue(struct qlcnic_adapter *adapter)
307 {
308         struct qlcnic_sriov *sriov = adapter->ahw->sriov;
309         struct qlcnic_back_channel *bc = &sriov->bc;
310         int i;
311
312         for (i = 0; i < sriov->num_vfs; i++)
313                 cancel_work_sync(&sriov->vf_info[i].flr_work);
314
315         destroy_workqueue(bc->bc_flr_wq);
316 }
317
318 static int qlcnic_sriov_pf_create_flr_queue(struct qlcnic_adapter *adapter)
319 {
320         struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc;
321         struct workqueue_struct *wq;
322
323         wq = create_singlethread_workqueue("qlcnic-flr");
324         if (wq == NULL) {
325                 dev_err(&adapter->pdev->dev, "Cannot create FLR workqueue\n");
326                 return -ENOMEM;
327         }
328
329         bc->bc_flr_wq =  wq;
330         return 0;
331 }
332
333 void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter)
334 {
335         u8 func = adapter->ahw->pci_func;
336
337         if (!qlcnic_sriov_enable_check(adapter))
338                 return;
339
340         qlcnic_sriov_pf_del_flr_queue(adapter);
341         qlcnic_sriov_cfg_bc_intr(adapter, 0);
342         qlcnic_sriov_pf_config_vport(adapter, 0, func);
343         qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0);
344         __qlcnic_sriov_cleanup(adapter);
345         adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
346         clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
347 }
348
349 void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter)
350 {
351         if (!qlcnic_sriov_pf_check(adapter))
352                 return;
353
354         if (!qlcnic_sriov_enable_check(adapter))
355                 return;
356
357         pci_disable_sriov(adapter->pdev);
358         netdev_info(adapter->netdev,
359                     "SR-IOV is disabled successfully on port %d\n",
360                     adapter->portnum);
361 }
362
363 static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter)
364 {
365         struct net_device *netdev = adapter->netdev;
366
367         if (netif_running(netdev))
368                 __qlcnic_down(adapter, netdev);
369
370         qlcnic_sriov_pf_disable(adapter);
371
372         qlcnic_sriov_pf_cleanup(adapter);
373
374         /* After disabling SRIOV re-init the driver in default mode
375            configure opmode based on op_mode of function
376          */
377         if (qlcnic_83xx_configure_opmode(adapter))
378                 return -EIO;
379
380         if (netif_running(netdev))
381                 __qlcnic_up(adapter, netdev);
382
383         return 0;
384 }
385
386 static int qlcnic_sriov_pf_init(struct qlcnic_adapter *adapter)
387 {
388         struct qlcnic_hardware_context *ahw = adapter->ahw;
389         struct qlcnic_info nic_info, pf_info, vp_info;
390         int err;
391         u8 func = ahw->pci_func;
392
393         if (!qlcnic_sriov_enable_check(adapter))
394                 return 0;
395
396         err = qlcnic_sriov_pf_cfg_eswitch(adapter, func, 1);
397         if (err)
398                 return err;
399
400         err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
401         if (err)
402                 goto disable_eswitch;
403
404         err = qlcnic_sriov_get_pf_info(adapter, &pf_info);
405         if (err)
406                 goto delete_vport;
407
408         err = qlcnic_get_nic_info(adapter, &nic_info, func);
409         if (err)
410                 goto delete_vport;
411
412         err = qlcnic_sriov_pf_cal_res_limit(adapter, &vp_info, func);
413         if (err)
414                 goto delete_vport;
415
416         err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
417         if (err)
418                 goto delete_vport;
419
420         ahw->physical_port = (u8) nic_info.phys_port;
421         ahw->switch_mode = nic_info.switch_mode;
422         ahw->max_mtu = nic_info.max_mtu;
423         ahw->capabilities = nic_info.capabilities;
424         ahw->nic_mode = QLC_83XX_SRIOV_MODE;
425         return err;
426
427 delete_vport:
428         qlcnic_sriov_pf_config_vport(adapter, 0, func);
429
430 disable_eswitch:
431         qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0);
432
433         return err;
434 }
435
436 static int qlcnic_sriov_pf_enable(struct qlcnic_adapter *adapter, int num_vfs)
437 {
438         int err;
439
440         if (!qlcnic_sriov_enable_check(adapter))
441                 return 0;
442
443         err = pci_enable_sriov(adapter->pdev, num_vfs);
444         if (err)
445                 qlcnic_sriov_pf_cleanup(adapter);
446
447         return err;
448 }
449
450 static int __qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter,
451                                      int num_vfs)
452 {
453         int err = 0;
454
455         set_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
456         adapter->ahw->op_mode = QLCNIC_SRIOV_PF_FUNC;
457
458         err = qlcnic_sriov_init(adapter, num_vfs);
459         if (err)
460                 goto clear_op_mode;
461
462         err = qlcnic_sriov_pf_create_flr_queue(adapter);
463         if (err)
464                 goto sriov_cleanup;
465
466         err = qlcnic_sriov_pf_init(adapter);
467         if (err)
468                 goto del_flr_queue;
469
470         err = qlcnic_sriov_pf_enable(adapter, num_vfs);
471         return err;
472
473 del_flr_queue:
474         qlcnic_sriov_pf_del_flr_queue(adapter);
475
476 sriov_cleanup:
477         __qlcnic_sriov_cleanup(adapter);
478
479 clear_op_mode:
480         clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
481         adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
482         return err;
483 }
484
485 static int qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, int num_vfs)
486 {
487         struct net_device *netdev = adapter->netdev;
488         int err;
489
490         if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
491                 netdev_err(netdev,
492                            "SR-IOV cannot be enabled, when legacy interrupts are enabled\n");
493                 return -EIO;
494         }
495
496         if (netif_running(netdev))
497                 __qlcnic_down(adapter, netdev);
498
499         err = __qlcnic_pci_sriov_enable(adapter, num_vfs);
500         if (err) {
501                 netdev_info(netdev, "Failed to enable SR-IOV on port %d\n",
502                             adapter->portnum);
503
504                 err = -EIO;
505                 if (qlcnic_83xx_configure_opmode(adapter))
506                         goto error;
507         } else {
508                 netdev_info(netdev,
509                             "SR-IOV is enabled successfully on port %d\n",
510                             adapter->portnum);
511                 /* Return number of vfs enabled */
512                 err = num_vfs;
513         }
514         if (netif_running(netdev))
515                 __qlcnic_up(adapter, netdev);
516
517 error:
518         return err;
519 }
520
521 int qlcnic_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
522 {
523         struct qlcnic_adapter *adapter = pci_get_drvdata(dev);
524         int err;
525
526         if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
527                 return -EBUSY;
528
529         if (num_vfs == 0)
530                 err = qlcnic_pci_sriov_disable(adapter);
531         else
532                 err = qlcnic_pci_sriov_enable(adapter, num_vfs);
533
534         clear_bit(__QLCNIC_RESETTING, &adapter->state);
535         return err;
536 }
537
538 static int qlcnic_sriov_set_vf_vport_info(struct qlcnic_adapter *adapter,
539                                           u16 func)
540 {
541         struct qlcnic_info defvp_info;
542         int err;
543
544         err = qlcnic_sriov_pf_cal_res_limit(adapter, &defvp_info, func);
545         if (err)
546                 return -EIO;
547
548         return 0;
549 }
550
551 static int qlcnic_sriov_pf_channel_cfg_cmd(struct qlcnic_bc_trans *trans,
552                                            struct qlcnic_cmd_args *cmd)
553 {
554         struct qlcnic_vf_info *vf = trans->vf;
555         struct qlcnic_adapter *adapter = vf->adapter;
556         int err;
557         u16 func = vf->pci_func;
558
559         cmd->rsp.arg[0] = trans->req_hdr->cmd_op;
560         cmd->rsp.arg[0] |= (1 << 16);
561
562         if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) {
563                 err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
564                 if (!err) {
565                         err = qlcnic_sriov_set_vf_vport_info(adapter, func);
566                         if (err)
567                                 qlcnic_sriov_pf_config_vport(adapter, 0, func);
568                 }
569         } else {
570                 err = qlcnic_sriov_pf_config_vport(adapter, 0, func);
571         }
572
573         if (err)
574                 goto err_out;
575
576         cmd->rsp.arg[0] |= (1 << 25);
577
578         if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT)
579                 set_bit(QLC_BC_VF_STATE, &vf->state);
580         else
581                 clear_bit(QLC_BC_VF_STATE, &vf->state);
582
583         return err;
584
585 err_out:
586         cmd->rsp.arg[0] |= (2 << 25);
587         return err;
588 }
589
590 static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter,
591                                        struct qlcnic_vport *vp,
592                                        u16 func, u16 vlan, u8 op)
593 {
594         struct qlcnic_cmd_args cmd;
595         struct qlcnic_macvlan_mbx mv;
596         u8 *addr;
597         int err;
598         u32 *buf;
599         int vpid;
600
601         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN))
602                 return -ENOMEM;
603
604         vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func);
605         if (vpid < 0) {
606                 err = -EINVAL;
607                 goto out;
608         }
609
610         if (vlan)
611                 op = ((op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
612                       QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL);
613
614         cmd.req.arg[1] = op | (1 << 8) | (3 << 6);
615         cmd.req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31;
616
617         addr = vp->mac;
618         mv.vlan = vlan;
619         mv.mac_addr0 = addr[0];
620         mv.mac_addr1 = addr[1];
621         mv.mac_addr2 = addr[2];
622         mv.mac_addr3 = addr[3];
623         mv.mac_addr4 = addr[4];
624         mv.mac_addr5 = addr[5];
625         buf = &cmd.req.arg[2];
626         memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
627
628         err = qlcnic_issue_cmd(adapter, &cmd);
629
630         if (err)
631                 dev_err(&adapter->pdev->dev,
632                         "MAC-VLAN %s to CAM failed, err=%d.\n",
633                         ((op == 1) ? "add " : "delete "), err);
634
635 out:
636         qlcnic_free_mbx_args(&cmd);
637         return err;
638 }
639
640 static int qlcnic_sriov_validate_create_rx_ctx(struct qlcnic_cmd_args *cmd)
641 {
642         if ((cmd->req.arg[0] >> 29) != 0x3)
643                 return -EINVAL;
644
645         return 0;
646 }
647
648 static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran,
649                                              struct qlcnic_cmd_args *cmd)
650 {
651         struct qlcnic_vf_info *vf = tran->vf;
652         struct qlcnic_adapter *adapter = vf->adapter;
653         struct qlcnic_rcv_mbx_out *mbx_out;
654         int err;
655
656         err = qlcnic_sriov_validate_create_rx_ctx(cmd);
657         if (err) {
658                 cmd->rsp.arg[0] |= (0x6 << 25);
659                 return err;
660         }
661
662         cmd->req.arg[6] = vf->vp->handle;
663         err = qlcnic_issue_cmd(adapter, cmd);
664
665         if (!err) {
666                 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd->rsp.arg[1];
667                 vf->rx_ctx_id = mbx_out->ctx_id;
668                 qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func,
669                                             0, QLCNIC_MAC_ADD);
670         } else {
671                 vf->rx_ctx_id = 0;
672         }
673
674         return err;
675 }
676
677 static int qlcnic_sriov_pf_mac_address_cmd(struct qlcnic_bc_trans *trans,
678                                            struct qlcnic_cmd_args *cmd)
679 {
680         struct qlcnic_vf_info *vf = trans->vf;
681         u8 type, *mac;
682
683         type = cmd->req.arg[1];
684         switch (type) {
685         case QLCNIC_SET_STATION_MAC:
686         case QLCNIC_SET_FAC_DEF_MAC:
687                 cmd->rsp.arg[0] = (2 << 25);
688                 break;
689         case QLCNIC_GET_CURRENT_MAC:
690                 cmd->rsp.arg[0] = (1 << 25);
691                 mac = vf->vp->mac;
692                 cmd->rsp.arg[2] = mac[1] | ((mac[0] << 8) & 0xff00);
693                 cmd->rsp.arg[1] = mac[5] | ((mac[4] << 8) & 0xff00) |
694                                   ((mac[3]) << 16 & 0xff0000) |
695                                   ((mac[2]) << 24 & 0xff000000);
696         }
697
698         return 0;
699 }
700
701 static int qlcnic_sriov_validate_create_tx_ctx(struct qlcnic_cmd_args *cmd)
702 {
703         if ((cmd->req.arg[0] >> 29) != 0x3)
704                 return -EINVAL;
705
706         return 0;
707 }
708
709 static int qlcnic_sriov_pf_create_tx_ctx_cmd(struct qlcnic_bc_trans *trans,
710                                              struct qlcnic_cmd_args *cmd)
711 {
712         struct qlcnic_vf_info *vf = trans->vf;
713         struct qlcnic_adapter *adapter = vf->adapter;
714         struct qlcnic_tx_mbx_out *mbx_out;
715         int err;
716
717         err = qlcnic_sriov_validate_create_tx_ctx(cmd);
718         if (err) {
719                 cmd->rsp.arg[0] |= (0x6 << 25);
720                 return err;
721         }
722
723         cmd->req.arg[5] |= vf->vp->handle << 16;
724         err = qlcnic_issue_cmd(adapter, cmd);
725         if (!err) {
726                 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd->rsp.arg[2];
727                 vf->tx_ctx_id = mbx_out->ctx_id;
728         } else {
729                 vf->tx_ctx_id = 0;
730         }
731
732         return err;
733 }
734
735 static int qlcnic_sriov_validate_del_rx_ctx(struct qlcnic_vf_info *vf,
736                                             struct qlcnic_cmd_args *cmd)
737 {
738         if ((cmd->req.arg[0] >> 29) != 0x3)
739                 return -EINVAL;
740
741         if ((cmd->req.arg[1] & 0xffff) != vf->rx_ctx_id)
742                 return -EINVAL;
743
744         return 0;
745 }
746
747 static int qlcnic_sriov_pf_del_rx_ctx_cmd(struct qlcnic_bc_trans *trans,
748                                           struct qlcnic_cmd_args *cmd)
749 {
750         struct qlcnic_vf_info *vf = trans->vf;
751         struct qlcnic_adapter *adapter = vf->adapter;
752         int err;
753
754         err = qlcnic_sriov_validate_del_rx_ctx(vf, cmd);
755         if (err) {
756                 cmd->rsp.arg[0] |= (0x6 << 25);
757                 return err;
758         }
759
760         qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func,
761                                     0, QLCNIC_MAC_DEL);
762         cmd->req.arg[1] |= vf->vp->handle << 16;
763         err = qlcnic_issue_cmd(adapter, cmd);
764
765         if (!err)
766                 vf->rx_ctx_id = 0;
767
768         return err;
769 }
770
771 static int qlcnic_sriov_validate_del_tx_ctx(struct qlcnic_vf_info *vf,
772                                             struct qlcnic_cmd_args *cmd)
773 {
774         if ((cmd->req.arg[0] >> 29) != 0x3)
775                 return -EINVAL;
776
777         if ((cmd->req.arg[1] & 0xffff) != vf->tx_ctx_id)
778                 return -EINVAL;
779
780         return 0;
781 }
782
783 static int qlcnic_sriov_pf_del_tx_ctx_cmd(struct qlcnic_bc_trans *trans,
784                                           struct qlcnic_cmd_args *cmd)
785 {
786         struct qlcnic_vf_info *vf = trans->vf;
787         struct qlcnic_adapter *adapter = vf->adapter;
788         int err;
789
790         err = qlcnic_sriov_validate_del_tx_ctx(vf, cmd);
791         if (err) {
792                 cmd->rsp.arg[0] |= (0x6 << 25);
793                 return err;
794         }
795
796         cmd->req.arg[1] |= vf->vp->handle << 16;
797         err = qlcnic_issue_cmd(adapter, cmd);
798
799         if (!err)
800                 vf->tx_ctx_id = 0;
801
802         return err;
803 }
804
805 static int qlcnic_sriov_validate_cfg_lro(struct qlcnic_vf_info *vf,
806                                          struct qlcnic_cmd_args *cmd)
807 {
808         if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
809                 return -EINVAL;
810
811         return 0;
812 }
813
814 static int qlcnic_sriov_pf_cfg_lro_cmd(struct qlcnic_bc_trans *trans,
815                                        struct qlcnic_cmd_args *cmd)
816 {
817         struct qlcnic_vf_info *vf = trans->vf;
818         struct qlcnic_adapter *adapter = vf->adapter;
819         int err;
820
821         err = qlcnic_sriov_validate_cfg_lro(vf, cmd);
822         if (err) {
823                 cmd->rsp.arg[0] |= (0x6 << 25);
824                 return err;
825         }
826
827         err = qlcnic_issue_cmd(adapter, cmd);
828         return err;
829 }
830
831 static int qlcnic_sriov_pf_cfg_ip_cmd(struct qlcnic_bc_trans *trans,
832                                       struct qlcnic_cmd_args *cmd)
833 {
834         struct qlcnic_vf_info *vf = trans->vf;
835         struct qlcnic_adapter *adapter = vf->adapter;
836         int err = -EIO;
837         u8 op;
838
839         op =  cmd->req.arg[1] & 0xff;
840
841         cmd->req.arg[1] |= vf->vp->handle << 16;
842         cmd->req.arg[1] |= BIT_31;
843
844         err = qlcnic_issue_cmd(adapter, cmd);
845         return err;
846 }
847
848 static int qlcnic_sriov_validate_cfg_intrpt(struct qlcnic_vf_info *vf,
849                                             struct qlcnic_cmd_args *cmd)
850 {
851         if (((cmd->req.arg[1] >> 8) & 0xff) != vf->pci_func)
852                 return -EINVAL;
853
854         if (!(cmd->req.arg[1] & BIT_16))
855                 return -EINVAL;
856
857         if ((cmd->req.arg[1] & 0xff) != 0x1)
858                 return -EINVAL;
859
860         return 0;
861 }
862
863 static int qlcnic_sriov_pf_cfg_intrpt_cmd(struct qlcnic_bc_trans *trans,
864                                           struct qlcnic_cmd_args *cmd)
865 {
866         struct qlcnic_vf_info *vf = trans->vf;
867         struct qlcnic_adapter *adapter = vf->adapter;
868         int err;
869
870         err = qlcnic_sriov_validate_cfg_intrpt(vf, cmd);
871         if (err)
872                 cmd->rsp.arg[0] |= (0x6 << 25);
873         else
874                 err = qlcnic_issue_cmd(adapter, cmd);
875
876         return err;
877 }
878
879 static int qlcnic_sriov_validate_mtu(struct qlcnic_adapter *adapter,
880                                      struct qlcnic_vf_info *vf,
881                                      struct qlcnic_cmd_args *cmd)
882 {
883         if (cmd->req.arg[1] != vf->rx_ctx_id)
884                 return -EINVAL;
885
886         if (cmd->req.arg[2] > adapter->ahw->max_mtu)
887                 return -EINVAL;
888
889         return 0;
890 }
891
892 static int qlcnic_sriov_pf_set_mtu_cmd(struct qlcnic_bc_trans *trans,
893                                        struct qlcnic_cmd_args *cmd)
894 {
895         struct qlcnic_vf_info *vf = trans->vf;
896         struct qlcnic_adapter *adapter = vf->adapter;
897         int err;
898
899         err = qlcnic_sriov_validate_mtu(adapter, vf, cmd);
900         if (err)
901                 cmd->rsp.arg[0] |= (0x6 << 25);
902         else
903                 err = qlcnic_issue_cmd(adapter, cmd);
904
905         return err;
906 }
907
908 static int qlcnic_sriov_validate_get_nic_info(struct qlcnic_vf_info *vf,
909                                               struct qlcnic_cmd_args *cmd)
910 {
911         if (cmd->req.arg[1] & BIT_31) {
912                 if (((cmd->req.arg[1] >> 16) & 0x7fff) != vf->pci_func)
913                         return -EINVAL;
914         } else {
915                 cmd->req.arg[1] |= vf->vp->handle << 16;
916         }
917
918         return 0;
919 }
920
921 static int qlcnic_sriov_pf_get_nic_info_cmd(struct qlcnic_bc_trans *trans,
922                                             struct qlcnic_cmd_args *cmd)
923 {
924         struct qlcnic_vf_info *vf = trans->vf;
925         struct qlcnic_adapter *adapter = vf->adapter;
926         int err;
927
928         err = qlcnic_sriov_validate_get_nic_info(vf, cmd);
929         if (err) {
930                 cmd->rsp.arg[0] |= (0x6 << 25);
931                 return err;
932         }
933
934         err = qlcnic_issue_cmd(adapter, cmd);
935         return err;
936 }
937
938 static int qlcnic_sriov_validate_cfg_rss(struct qlcnic_vf_info *vf,
939                                          struct qlcnic_cmd_args *cmd)
940 {
941         if (cmd->req.arg[1] != vf->rx_ctx_id)
942                 return -EINVAL;
943
944         return 0;
945 }
946
947 static int qlcnic_sriov_pf_cfg_rss_cmd(struct qlcnic_bc_trans *trans,
948                                        struct qlcnic_cmd_args *cmd)
949 {
950         struct qlcnic_vf_info *vf = trans->vf;
951         struct qlcnic_adapter *adapter = vf->adapter;
952         int err;
953
954         err = qlcnic_sriov_validate_cfg_rss(vf, cmd);
955         if (err)
956                 cmd->rsp.arg[0] |= (0x6 << 25);
957         else
958                 err = qlcnic_issue_cmd(adapter, cmd);
959
960         return err;
961 }
962
963 static int qlcnic_sriov_validate_cfg_intrcoal(struct qlcnic_adapter *adapter,
964                                               struct qlcnic_vf_info *vf,
965                                               struct qlcnic_cmd_args *cmd)
966 {
967         struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
968         u16 ctx_id, pkts, time;
969
970         ctx_id = cmd->req.arg[1] >> 16;
971         pkts = cmd->req.arg[2] & 0xffff;
972         time = cmd->req.arg[2] >> 16;
973
974         if (ctx_id != vf->rx_ctx_id)
975                 return -EINVAL;
976         if (pkts > coal->rx_packets)
977                 return -EINVAL;
978         if (time < coal->rx_time_us)
979                 return -EINVAL;
980
981         return 0;
982 }
983
984 static int qlcnic_sriov_pf_cfg_intrcoal_cmd(struct qlcnic_bc_trans *tran,
985                                             struct qlcnic_cmd_args *cmd)
986 {
987         struct qlcnic_vf_info *vf = tran->vf;
988         struct qlcnic_adapter *adapter = vf->adapter;
989         int err;
990
991         err = qlcnic_sriov_validate_cfg_intrcoal(adapter, vf, cmd);
992         if (err) {
993                 cmd->rsp.arg[0] |= (0x6 << 25);
994                 return err;
995         }
996
997         err = qlcnic_issue_cmd(adapter, cmd);
998         return err;
999 }
1000
1001 static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter,
1002                                              struct qlcnic_vf_info *vf,
1003                                              struct qlcnic_cmd_args *cmd)
1004 {
1005         struct qlcnic_macvlan_mbx *macvlan;
1006
1007         if (!(cmd->req.arg[1] & BIT_8))
1008                 return -EINVAL;
1009
1010         cmd->req.arg[1] |= (vf->vp->handle << 16);
1011         cmd->req.arg[1] |= BIT_31;
1012
1013         macvlan = (struct qlcnic_macvlan_mbx *)&cmd->req.arg[2];
1014         if (!(macvlan->mac_addr0 & BIT_0)) {
1015                 dev_err(&adapter->pdev->dev,
1016                         "MAC address change is not allowed from VF %d",
1017                         vf->pci_func);
1018                 return -EINVAL;
1019         }
1020
1021         return 0;
1022 }
1023
1024 static int qlcnic_sriov_pf_cfg_macvlan_cmd(struct qlcnic_bc_trans *trans,
1025                                            struct qlcnic_cmd_args *cmd)
1026 {
1027         struct qlcnic_vf_info *vf = trans->vf;
1028         struct qlcnic_adapter *adapter = vf->adapter;
1029         int err;
1030
1031         err = qlcnic_sriov_validate_cfg_macvlan(adapter, vf, cmd);
1032         if (err) {
1033                 cmd->rsp.arg[0] |= (0x6 << 25);
1034                 return err;
1035         }
1036
1037         err = qlcnic_issue_cmd(adapter, cmd);
1038         return err;
1039 }
1040
1041 static int qlcnic_sriov_validate_linkevent(struct qlcnic_vf_info *vf,
1042                                            struct qlcnic_cmd_args *cmd)
1043 {
1044         if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
1045                 return -EINVAL;
1046
1047         if (!(cmd->req.arg[1] & BIT_8))
1048                 return -EINVAL;
1049
1050         return 0;
1051 }
1052
1053 static int qlcnic_sriov_pf_linkevent_cmd(struct qlcnic_bc_trans *trans,
1054                                          struct qlcnic_cmd_args *cmd)
1055 {
1056         struct qlcnic_vf_info *vf = trans->vf;
1057         struct qlcnic_adapter *adapter = vf->adapter;
1058         int err;
1059
1060         err = qlcnic_sriov_validate_linkevent(vf, cmd);
1061         if (err) {
1062                 cmd->rsp.arg[0] |= (0x6 << 25);
1063                 return err;
1064         }
1065
1066         err = qlcnic_issue_cmd(adapter, cmd);
1067         return err;
1068 }
1069
1070 static int qlcnic_sriov_pf_cfg_promisc_cmd(struct qlcnic_bc_trans *trans,
1071                                            struct qlcnic_cmd_args *cmd)
1072 {
1073         struct qlcnic_vf_info *vf = trans->vf;
1074         struct qlcnic_adapter *adapter = vf->adapter;
1075         int err;
1076
1077         cmd->req.arg[1] |= vf->vp->handle << 16;
1078         cmd->req.arg[1] |= BIT_31;
1079         err = qlcnic_issue_cmd(adapter, cmd);
1080         return err;
1081 }
1082
1083 static const int qlcnic_pf_passthru_supp_cmds[] = {
1084         QLCNIC_CMD_GET_STATISTICS,
1085         QLCNIC_CMD_GET_PORT_CONFIG,
1086         QLCNIC_CMD_GET_LINK_STATUS,
1087 };
1088
1089 static const struct qlcnic_sriov_cmd_handler qlcnic_pf_bc_cmd_hdlr[] = {
1090         [QLCNIC_BC_CMD_CHANNEL_INIT] = {&qlcnic_sriov_pf_channel_cfg_cmd},
1091         [QLCNIC_BC_CMD_CHANNEL_TERM] = {&qlcnic_sriov_pf_channel_cfg_cmd},
1092 };
1093
1094 static const struct qlcnic_sriov_fw_cmd_handler qlcnic_pf_fw_cmd_hdlr[] = {
1095         {QLCNIC_CMD_CREATE_RX_CTX, qlcnic_sriov_pf_create_rx_ctx_cmd},
1096         {QLCNIC_CMD_CREATE_TX_CTX, qlcnic_sriov_pf_create_tx_ctx_cmd},
1097         {QLCNIC_CMD_MAC_ADDRESS, qlcnic_sriov_pf_mac_address_cmd},
1098         {QLCNIC_CMD_DESTROY_RX_CTX, qlcnic_sriov_pf_del_rx_ctx_cmd},
1099         {QLCNIC_CMD_DESTROY_TX_CTX, qlcnic_sriov_pf_del_tx_ctx_cmd},
1100         {QLCNIC_CMD_CONFIGURE_HW_LRO, qlcnic_sriov_pf_cfg_lro_cmd},
1101         {QLCNIC_CMD_CONFIGURE_IP_ADDR, qlcnic_sriov_pf_cfg_ip_cmd},
1102         {QLCNIC_CMD_CONFIG_INTRPT, qlcnic_sriov_pf_cfg_intrpt_cmd},
1103         {QLCNIC_CMD_SET_MTU, qlcnic_sriov_pf_set_mtu_cmd},
1104         {QLCNIC_CMD_GET_NIC_INFO, qlcnic_sriov_pf_get_nic_info_cmd},
1105         {QLCNIC_CMD_CONFIGURE_RSS, qlcnic_sriov_pf_cfg_rss_cmd},
1106         {QLCNIC_CMD_CONFIG_INTR_COAL, qlcnic_sriov_pf_cfg_intrcoal_cmd},
1107         {QLCNIC_CMD_CONFIG_MAC_VLAN, qlcnic_sriov_pf_cfg_macvlan_cmd},
1108         {QLCNIC_CMD_GET_LINK_EVENT, qlcnic_sriov_pf_linkevent_cmd},
1109         {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, qlcnic_sriov_pf_cfg_promisc_cmd},
1110 };
1111
1112 void qlcnic_sriov_pf_process_bc_cmd(struct qlcnic_adapter *adapter,
1113                                     struct qlcnic_bc_trans *trans,
1114                                     struct qlcnic_cmd_args *cmd)
1115 {
1116         u8 size, cmd_op;
1117
1118         cmd_op = trans->req_hdr->cmd_op;
1119
1120         if (trans->req_hdr->op_type == QLC_BC_CMD) {
1121                 size = ARRAY_SIZE(qlcnic_pf_bc_cmd_hdlr);
1122                 if (cmd_op < size) {
1123                         qlcnic_pf_bc_cmd_hdlr[cmd_op].fn(trans, cmd);
1124                         return;
1125                 }
1126         } else {
1127                 int i;
1128                 size = ARRAY_SIZE(qlcnic_pf_fw_cmd_hdlr);
1129                 for (i = 0; i < size; i++) {
1130                         if (cmd_op == qlcnic_pf_fw_cmd_hdlr[i].cmd) {
1131                                 qlcnic_pf_fw_cmd_hdlr[i].fn(trans, cmd);
1132                                 return;
1133                         }
1134                 }
1135
1136                 size = ARRAY_SIZE(qlcnic_pf_passthru_supp_cmds);
1137                 for (i = 0; i < size; i++) {
1138                         if (cmd_op == qlcnic_pf_passthru_supp_cmds[i]) {
1139                                 qlcnic_issue_cmd(adapter, cmd);
1140                                 return;
1141                         }
1142                 }
1143         }
1144
1145         cmd->rsp.arg[0] |= (0x9 << 25);
1146 }
1147
1148 void qlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *adapter,
1149                                              u32 *int_id)
1150 {
1151         u16 vpid;
1152
1153         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1154                                                 adapter->ahw->pci_func);
1155         *int_id |= vpid;
1156 }
1157
1158 void qlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *adapter,
1159                                            u32 *int_id)
1160 {
1161         u16 vpid;
1162
1163         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1164                                                 adapter->ahw->pci_func);
1165         *int_id |= vpid << 16;
1166 }
1167
1168 void qlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *adapter,
1169                                               u32 *int_id)
1170 {
1171         int vpid;
1172
1173         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1174                                                 adapter->ahw->pci_func);
1175         *int_id |= vpid << 16;
1176 }
1177
1178 void qlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *adapter,
1179                                            u32 *int_id)
1180 {
1181         u16 vpid;
1182
1183         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1184                                                 adapter->ahw->pci_func);
1185         *int_id |= vpid << 16;
1186 }
1187
1188 void qlcnic_pf_set_interface_id_promisc(struct qlcnic_adapter *adapter,
1189                                         u32 *int_id)
1190 {
1191         u16 vpid;
1192
1193         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1194                                                 adapter->ahw->pci_func);
1195         *int_id |= (vpid << 16) | BIT_31;
1196 }
1197
1198 void qlcnic_pf_set_interface_id_ipaddr(struct qlcnic_adapter *adapter,
1199                                        u32 *int_id)
1200 {
1201         u16 vpid;
1202
1203         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1204                                                 adapter->ahw->pci_func);
1205         *int_id |= (vpid << 16) | BIT_31;
1206 }
1207
1208 void qlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
1209                                         u32 *int_id)
1210 {
1211         u16 vpid;
1212
1213         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1214                                                 adapter->ahw->pci_func);
1215         *int_id |= (vpid << 16) | BIT_31;
1216 }
1217
1218 static void qlcnic_sriov_del_rx_ctx(struct qlcnic_adapter *adapter,
1219                                     struct qlcnic_vf_info *vf)
1220 {
1221         struct qlcnic_cmd_args cmd;
1222         int vpid;
1223
1224         if (!vf->rx_ctx_id)
1225                 return;
1226
1227         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_RX_CTX))
1228                 return;
1229
1230         vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func);
1231         if (vpid >= 0) {
1232                 cmd.req.arg[1] = vf->rx_ctx_id | (vpid & 0xffff) << 16;
1233                 if (qlcnic_issue_cmd(adapter, &cmd))
1234                         dev_err(&adapter->pdev->dev,
1235                                 "Failed to delete Tx ctx in firmware for func 0x%x\n",
1236                                 vf->pci_func);
1237                 else
1238                         vf->rx_ctx_id = 0;
1239         }
1240
1241         qlcnic_free_mbx_args(&cmd);
1242 }
1243
1244 static void qlcnic_sriov_del_tx_ctx(struct qlcnic_adapter *adapter,
1245                                     struct qlcnic_vf_info *vf)
1246 {
1247         struct qlcnic_cmd_args cmd;
1248         int vpid;
1249
1250         if (!vf->tx_ctx_id)
1251                 return;
1252
1253         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_DESTROY_TX_CTX))
1254                 return;
1255
1256         vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func);
1257         if (vpid >= 0) {
1258                 cmd.req.arg[1] |= vf->tx_ctx_id | (vpid & 0xffff) << 16;
1259                 if (qlcnic_issue_cmd(adapter, &cmd))
1260                         dev_err(&adapter->pdev->dev,
1261                                 "Failed to delete Tx ctx in firmware for func 0x%x\n",
1262                                 vf->pci_func);
1263                 else
1264                         vf->tx_ctx_id = 0;
1265         }
1266
1267         qlcnic_free_mbx_args(&cmd);
1268 }
1269
1270 static int qlcnic_sriov_add_act_list_irqsave(struct qlcnic_sriov *sriov,
1271                                              struct qlcnic_vf_info *vf,
1272                                              struct qlcnic_bc_trans *trans)
1273 {
1274         struct qlcnic_trans_list *t_list = &vf->rcv_act;
1275         unsigned long flag;
1276
1277         spin_lock_irqsave(&t_list->lock, flag);
1278
1279         __qlcnic_sriov_add_act_list(sriov, vf, trans);
1280
1281         spin_unlock_irqrestore(&t_list->lock, flag);
1282         return 0;
1283 }
1284
1285 static void __qlcnic_sriov_process_flr(struct qlcnic_vf_info *vf)
1286 {
1287         struct qlcnic_adapter *adapter = vf->adapter;
1288
1289         qlcnic_sriov_cleanup_list(&vf->rcv_pend);
1290         cancel_work_sync(&vf->trans_work);
1291         qlcnic_sriov_cleanup_list(&vf->rcv_act);
1292
1293         if (test_bit(QLC_BC_VF_SOFT_FLR, &vf->state)) {
1294                 qlcnic_sriov_del_tx_ctx(adapter, vf);
1295                 qlcnic_sriov_del_rx_ctx(adapter, vf);
1296         }
1297
1298         qlcnic_sriov_pf_config_vport(adapter, 0, vf->pci_func);
1299
1300         clear_bit(QLC_BC_VF_FLR, &vf->state);
1301         if (test_bit(QLC_BC_VF_SOFT_FLR, &vf->state)) {
1302                 qlcnic_sriov_add_act_list_irqsave(adapter->ahw->sriov, vf,
1303                                                   vf->flr_trans);
1304                 clear_bit(QLC_BC_VF_SOFT_FLR, &vf->state);
1305                 vf->flr_trans = NULL;
1306         }
1307 }
1308
1309 static void qlcnic_sriov_pf_process_flr(struct work_struct *work)
1310 {
1311         struct qlcnic_vf_info *vf;
1312
1313         vf = container_of(work, struct qlcnic_vf_info, flr_work);
1314         __qlcnic_sriov_process_flr(vf);
1315         return;
1316 }
1317
1318 static void qlcnic_sriov_schedule_flr(struct qlcnic_sriov *sriov,
1319                                       struct qlcnic_vf_info *vf,
1320                                       work_func_t func)
1321 {
1322         if (test_bit(__QLCNIC_RESETTING, &vf->adapter->state))
1323                 return;
1324
1325         INIT_WORK(&vf->flr_work, func);
1326         queue_work(sriov->bc.bc_flr_wq, &vf->flr_work);
1327 }
1328
1329 static void qlcnic_sriov_handle_soft_flr(struct qlcnic_adapter *adapter,
1330                                          struct qlcnic_bc_trans *trans,
1331                                          struct qlcnic_vf_info *vf)
1332 {
1333         struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1334
1335         set_bit(QLC_BC_VF_FLR, &vf->state);
1336         clear_bit(QLC_BC_VF_STATE, &vf->state);
1337         set_bit(QLC_BC_VF_SOFT_FLR, &vf->state);
1338         vf->flr_trans = trans;
1339         qlcnic_sriov_schedule_flr(sriov, vf, qlcnic_sriov_pf_process_flr);
1340         netdev_info(adapter->netdev, "Software FLR for PCI func %d\n",
1341                     vf->pci_func);
1342 }
1343
1344 bool qlcnic_sriov_soft_flr_check(struct qlcnic_adapter *adapter,
1345                                  struct qlcnic_bc_trans *trans,
1346                                  struct qlcnic_vf_info *vf)
1347 {
1348         struct qlcnic_bc_hdr *hdr = trans->req_hdr;
1349
1350         if ((hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) &&
1351             (hdr->op_type == QLC_BC_CMD) &&
1352              test_bit(QLC_BC_VF_STATE, &vf->state)) {
1353                 qlcnic_sriov_handle_soft_flr(adapter, trans, vf);
1354                 return true;
1355         }
1356
1357         return false;
1358 }
1359
1360 void qlcnic_sriov_pf_handle_flr(struct qlcnic_sriov *sriov,
1361                                 struct qlcnic_vf_info *vf)
1362 {
1363         struct net_device *dev = vf->adapter->netdev;
1364
1365         if (!test_and_clear_bit(QLC_BC_VF_STATE, &vf->state)) {
1366                 clear_bit(QLC_BC_VF_FLR, &vf->state);
1367                 return;
1368         }
1369
1370         if (test_and_set_bit(QLC_BC_VF_FLR, &vf->state)) {
1371                 netdev_info(dev, "FLR for PCI func %d in progress\n",
1372                             vf->pci_func);
1373                 return;
1374         }
1375
1376         qlcnic_sriov_schedule_flr(sriov, vf, qlcnic_sriov_pf_process_flr);
1377         netdev_info(dev, "FLR received for PCI func %d\n", vf->pci_func);
1378 }
1379
1380 void qlcnic_sriov_pf_reset(struct qlcnic_adapter *adapter)
1381 {
1382         struct qlcnic_hardware_context *ahw = adapter->ahw;
1383         struct qlcnic_sriov *sriov = ahw->sriov;
1384         struct qlcnic_vf_info *vf;
1385         u16 num_vfs = sriov->num_vfs;
1386         int i;
1387
1388         for (i = 0; i < num_vfs; i++) {
1389                 vf = &sriov->vf_info[i];
1390                 vf->rx_ctx_id = 0;
1391                 vf->tx_ctx_id = 0;
1392                 cancel_work_sync(&vf->flr_work);
1393                 __qlcnic_sriov_process_flr(vf);
1394                 clear_bit(QLC_BC_VF_STATE, &vf->state);
1395         }
1396
1397         qlcnic_sriov_pf_reset_vport_handle(adapter, ahw->pci_func);
1398         QLCWRX(ahw, QLCNIC_MBX_INTR_ENBL, (ahw->num_msix - 1) << 8);
1399 }
1400
1401 int qlcnic_sriov_pf_reinit(struct qlcnic_adapter *adapter)
1402 {
1403         struct qlcnic_hardware_context *ahw = adapter->ahw;
1404         int err;
1405
1406         if (!qlcnic_sriov_enable_check(adapter))
1407                 return 0;
1408
1409         ahw->op_mode = QLCNIC_SRIOV_PF_FUNC;
1410
1411         err = qlcnic_sriov_pf_init(adapter);
1412         if (err)
1413                 return err;
1414
1415         dev_info(&adapter->pdev->dev, "%s: op_mode %d\n",
1416                  __func__, ahw->op_mode);
1417         return err;
1418 }