qlcnic: Support VF-PF communication channel commands.
[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         dev_info(&adapter->pdev->dev,
160                  "\n\ttotal_pf: %d,\n"
161                  "\n\ttotal_rss_engines: %d max_vports: %d max_tx_ques %d,\n"
162                  "\tmax_tx_mac_filters: %d max_rx_mcast_mac_filters: %d,\n"
163                  "\tmax_rx_ucast_mac_filters: 0x%x, max_rx_ip_addr: %d,\n"
164                  "\tmax_rx_lro_flow: %d max_rx_status_rings: %d,\n"
165                  "\tmax_rx_buf_rings: %d, max_rx_ques: %d, max_tx_vlan_keys %d\n"
166                  "\tmax_local_ipv6_addrs: %d, max_remote_ipv6_addrs: %d\n",
167                  npar_info->total_pf, npar_info->total_rss_engines,
168                  npar_info->max_vports, npar_info->max_tx_ques,
169                  npar_info->max_tx_mac_filters,
170                  npar_info->max_rx_mcast_mac_filters,
171                  npar_info->max_rx_ucast_mac_filters, npar_info->max_rx_ip_addr,
172                  npar_info->max_rx_lro_flow, npar_info->max_rx_status_rings,
173                  npar_info->max_rx_buf_rings, npar_info->max_rx_ques,
174                  npar_info->max_tx_vlan_keys, npar_info->max_local_ipv6_addrs,
175                  npar_info->max_remote_ipv6_addrs);
176
177 out:
178         qlcnic_free_mbx_args(&cmd);
179         return err;
180 }
181
182 static void qlcnic_sriov_pf_reset_vport_handle(struct qlcnic_adapter *adapter,
183                                                u8 func)
184 {
185         struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
186         struct qlcnic_vport *vp;
187         int index;
188
189         if (adapter->ahw->pci_func == func) {
190                 sriov->vp_handle = 0;
191         } else {
192                 index = qlcnic_sriov_func_to_index(adapter, func);
193                 if (index < 0)
194                         return;
195                 vp = sriov->vf_info[index].vp;
196                 vp->handle = 0;
197         }
198 }
199
200 static void qlcnic_sriov_pf_set_vport_handle(struct qlcnic_adapter *adapter,
201                                              u16 vport_handle, u8 func)
202 {
203         struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
204         struct qlcnic_vport *vp;
205         int index;
206
207         if (adapter->ahw->pci_func == func) {
208                 sriov->vp_handle = vport_handle;
209         } else {
210                 index = qlcnic_sriov_func_to_index(adapter, func);
211                 if (index < 0)
212                         return;
213                 vp = sriov->vf_info[index].vp;
214                 vp->handle = vport_handle;
215         }
216 }
217
218 static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *adapter,
219                                             u8 func)
220 {
221         struct qlcnic_sriov  *sriov = adapter->ahw->sriov;
222         struct qlcnic_vf_info *vf_info;
223         int index;
224
225         if (adapter->ahw->pci_func == func) {
226                 return sriov->vp_handle;
227         } else {
228                 index = qlcnic_sriov_func_to_index(adapter, func);
229                 if (index >= 0) {
230                         vf_info = &sriov->vf_info[index];
231                         return vf_info->vp->handle;
232                 }
233         }
234
235         return -EINVAL;
236 }
237
238 static int qlcnic_sriov_pf_config_vport(struct qlcnic_adapter *adapter,
239                                         u8 flag, u16 func)
240 {
241         struct qlcnic_cmd_args cmd;
242         int ret;
243         int vpid;
244
245         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_VPORT))
246                 return -ENOMEM;
247
248         if (flag) {
249                 cmd.req.arg[3] = func << 8;
250         } else {
251                 vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func);
252                 if (vpid < 0) {
253                         ret = -EINVAL;
254                         goto out;
255                 }
256                 cmd.req.arg[3] = ((vpid & 0xffff) << 8) | 1;
257         }
258
259         ret = qlcnic_issue_cmd(adapter, &cmd);
260         if (ret) {
261                 dev_err(&adapter->pdev->dev,
262                         "Failed %s vport, err %d for func 0x%x\n",
263                         (flag ? "enable" : "disable"), ret, func);
264                 goto out;
265         }
266
267         if (flag) {
268                 vpid = cmd.rsp.arg[2] & 0xffff;
269                 qlcnic_sriov_pf_set_vport_handle(adapter, vpid, func);
270         } else {
271                 qlcnic_sriov_pf_reset_vport_handle(adapter, func);
272         }
273
274 out:
275         qlcnic_free_mbx_args(&cmd);
276         return ret;
277 }
278
279 static int qlcnic_sriov_pf_cfg_eswitch(struct qlcnic_adapter *adapter,
280                                        u8 func, u8 enable)
281 {
282         struct qlcnic_cmd_args cmd;
283         int err = -EIO;
284
285         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_TOGGLE_ESWITCH))
286                 return -ENOMEM;
287
288         cmd.req.arg[0] |= (3 << 29);
289         cmd.req.arg[1] = ((func & 0xf) << 2) | BIT_6 | BIT_1;
290         if (enable)
291                 cmd.req.arg[1] |= BIT_0;
292
293         err = qlcnic_issue_cmd(adapter, &cmd);
294
295         if (err != QLCNIC_RCODE_SUCCESS) {
296                 dev_err(&adapter->pdev->dev,
297                         "Failed to enable sriov eswitch%d\n", err);
298                 err = -EIO;
299         }
300
301         qlcnic_free_mbx_args(&cmd);
302         return err;
303 }
304
305 void qlcnic_sriov_pf_cleanup(struct qlcnic_adapter *adapter)
306 {
307         u8 func = adapter->ahw->pci_func;
308
309         if (!qlcnic_sriov_enable_check(adapter))
310                 return;
311
312         qlcnic_sriov_cfg_bc_intr(adapter, 0);
313         qlcnic_sriov_pf_config_vport(adapter, 0, func);
314         qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0);
315         __qlcnic_sriov_cleanup(adapter);
316         adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
317         clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
318 }
319
320 void qlcnic_sriov_pf_disable(struct qlcnic_adapter *adapter)
321 {
322         if (!qlcnic_sriov_pf_check(adapter))
323                 return;
324
325         if (!qlcnic_sriov_enable_check(adapter))
326                 return;
327
328         pci_disable_sriov(adapter->pdev);
329         netdev_info(adapter->netdev,
330                     "SR-IOV is disabled successfully on port %d\n",
331                     adapter->portnum);
332 }
333
334 static int qlcnic_pci_sriov_disable(struct qlcnic_adapter *adapter)
335 {
336         struct net_device *netdev = adapter->netdev;
337
338         if (netif_running(netdev))
339                 __qlcnic_down(adapter, netdev);
340
341         qlcnic_sriov_pf_disable(adapter);
342
343         qlcnic_sriov_pf_cleanup(adapter);
344
345         /* After disabling SRIOV re-init the driver in default mode
346            configure opmode based on op_mode of function
347          */
348         if (qlcnic_83xx_configure_opmode(adapter))
349                 return -EIO;
350
351         if (netif_running(netdev))
352                 __qlcnic_up(adapter, netdev);
353
354         return 0;
355 }
356
357 static int qlcnic_sriov_pf_init(struct qlcnic_adapter *adapter)
358 {
359         struct qlcnic_hardware_context *ahw = adapter->ahw;
360         struct qlcnic_info nic_info, pf_info, vp_info;
361         int err;
362         u8 func = ahw->pci_func;
363
364         if (!qlcnic_sriov_enable_check(adapter))
365                 return 0;
366
367         err = qlcnic_sriov_pf_cfg_eswitch(adapter, func, 1);
368         if (err)
369                 goto clear_sriov_enable;
370
371         err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
372         if (err)
373                 goto disable_eswitch;
374
375         err = qlcnic_sriov_get_pf_info(adapter, &pf_info);
376         if (err)
377                 goto delete_vport;
378
379         qlcnic_sriov_pf_set_ff_max_res(adapter, &pf_info);
380
381         err = qlcnic_get_nic_info(adapter, &nic_info, func);
382         if (err)
383                 goto delete_vport;
384
385         err = qlcnic_sriov_pf_cal_res_limit(adapter, &vp_info, func);
386         if (err)
387                 goto delete_vport;
388
389         err = qlcnic_sriov_cfg_bc_intr(adapter, 1);
390         if (err)
391                 goto delete_vport;
392
393         ahw->physical_port = (u8) nic_info.phys_port;
394         ahw->switch_mode = nic_info.switch_mode;
395         ahw->max_mtu = nic_info.max_mtu;
396         ahw->capabilities = nic_info.capabilities;
397         ahw->nic_mode = QLC_83XX_SRIOV_MODE;
398         return err;
399
400 delete_vport:
401         qlcnic_sriov_pf_config_vport(adapter, 0, func);
402
403 disable_eswitch:
404         qlcnic_sriov_pf_cfg_eswitch(adapter, func, 0);
405
406 clear_sriov_enable:
407         __qlcnic_sriov_cleanup(adapter);
408         adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
409         clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
410         return err;
411 }
412
413 static int qlcnic_sriov_pf_enable(struct qlcnic_adapter *adapter, int num_vfs)
414 {
415         int err;
416
417         if (!qlcnic_sriov_enable_check(adapter))
418                 return 0;
419
420         err = pci_enable_sriov(adapter->pdev, num_vfs);
421         if (err)
422                 qlcnic_sriov_pf_cleanup(adapter);
423
424         return err;
425 }
426
427 static int __qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter,
428                                      int num_vfs)
429 {
430         int err = 0;
431
432         set_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
433         adapter->ahw->op_mode = QLCNIC_SRIOV_PF_FUNC;
434
435         if (qlcnic_sriov_init(adapter, num_vfs)) {
436                 clear_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
437                 adapter->ahw->op_mode = QLCNIC_MGMT_FUNC;
438                 return -EIO;
439         }
440
441         if (qlcnic_sriov_pf_init(adapter))
442                 return -EIO;
443
444         err = qlcnic_sriov_pf_enable(adapter, num_vfs);
445         return err;
446 }
447
448 static int qlcnic_pci_sriov_enable(struct qlcnic_adapter *adapter, int num_vfs)
449 {
450         struct net_device *netdev = adapter->netdev;
451         int err;
452
453         if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
454                 netdev_err(netdev,
455                            "SR-IOV cannot be enabled, when legacy interrupts are enabled\n");
456                 return -EIO;
457         }
458
459         if (netif_running(netdev))
460                 __qlcnic_down(adapter, netdev);
461
462         err = __qlcnic_pci_sriov_enable(adapter, num_vfs);
463         if (err) {
464                 netdev_info(netdev, "Failed to enable SR-IOV on port %d\n",
465                             adapter->portnum);
466
467                 if (qlcnic_83xx_configure_opmode(adapter))
468                         goto error;
469         } else {
470                 netdev_info(adapter->netdev,
471                             "SR-IOV is enabled successfully on port %d\n",
472                             adapter->portnum);
473         }
474         if (netif_running(netdev))
475                 __qlcnic_up(adapter, netdev);
476
477 error:
478         return err;
479 }
480
481 int qlcnic_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
482 {
483         struct qlcnic_adapter *adapter = pci_get_drvdata(dev);
484         int err;
485
486         if (test_and_set_bit(__QLCNIC_RESETTING, &adapter->state))
487                 return -EBUSY;
488
489         if (num_vfs == 0)
490                 err = qlcnic_pci_sriov_disable(adapter);
491         else
492                 err = qlcnic_pci_sriov_enable(adapter, num_vfs);
493
494         clear_bit(__QLCNIC_RESETTING, &adapter->state);
495         return err;
496 }
497
498 static int qlcnic_sriov_set_vf_vport_info(struct qlcnic_adapter *adapter,
499                                           u16 func)
500 {
501         struct qlcnic_info defvp_info;
502         int err;
503
504         err = qlcnic_sriov_pf_cal_res_limit(adapter, &defvp_info, func);
505         if (err)
506                 return -EIO;
507
508         return 0;
509 }
510
511 static int qlcnic_sriov_pf_channel_cfg_cmd(struct qlcnic_bc_trans *trans,
512                                            struct qlcnic_cmd_args *cmd)
513 {
514         struct qlcnic_vf_info *vf = trans->vf;
515         struct qlcnic_adapter *adapter = vf->adapter;
516         int err;
517         u16 func = vf->pci_func;
518
519         cmd->rsp.arg[0] = trans->req_hdr->cmd_op;
520         cmd->rsp.arg[0] |= (1 << 16);
521
522         if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT) {
523                 err = qlcnic_sriov_pf_config_vport(adapter, 1, func);
524                 if (!err) {
525                         err = qlcnic_sriov_set_vf_vport_info(adapter, func);
526                         if (err)
527                                 qlcnic_sriov_pf_config_vport(adapter, 0, func);
528                 }
529         } else {
530                 err = qlcnic_sriov_pf_config_vport(adapter, 0, func);
531         }
532
533         if (err)
534                 goto err_out;
535
536         cmd->rsp.arg[0] |= (1 << 25);
537
538         if (trans->req_hdr->cmd_op == QLCNIC_BC_CMD_CHANNEL_INIT)
539                 set_bit(QLC_BC_VF_STATE, &vf->state);
540         else
541                 clear_bit(QLC_BC_VF_STATE, &vf->state);
542
543         return err;
544
545 err_out:
546         cmd->rsp.arg[0] |= (2 << 25);
547         return err;
548 }
549
550 static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter,
551                                        struct qlcnic_vport *vp,
552                                        u16 func, __le16 vlan, u8 op)
553 {
554         struct qlcnic_cmd_args cmd;
555         struct qlcnic_macvlan_mbx mv;
556         u8 *addr;
557         int err;
558         u32 *buf;
559         int vpid;
560
561         if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN))
562                 return -ENOMEM;
563
564         vpid = qlcnic_sriov_pf_get_vport_handle(adapter, func);
565         if (vpid < 0) {
566                 err = -EINVAL;
567                 goto out;
568         }
569
570         if (vlan)
571                 op = ((op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
572                       QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL);
573
574         cmd.req.arg[1] = op | (1 << 8) | (3 << 6);
575         cmd.req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31;
576
577         addr = vp->mac;
578         mv.vlan = le16_to_cpu(vlan);
579         mv.mac_addr0 = addr[0];
580         mv.mac_addr1 = addr[1];
581         mv.mac_addr2 = addr[2];
582         mv.mac_addr3 = addr[3];
583         mv.mac_addr4 = addr[4];
584         mv.mac_addr5 = addr[5];
585         buf = &cmd.req.arg[2];
586         memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
587
588         err = qlcnic_issue_cmd(adapter, &cmd);
589
590         if (err)
591                 dev_err(&adapter->pdev->dev,
592                         "MAC-VLAN %s to CAM failed, err=%d.\n",
593                         ((op == 1) ? "add " : "delete "), err);
594
595 out:
596         qlcnic_free_mbx_args(&cmd);
597         return err;
598 }
599
600 static int qlcnic_sriov_validate_create_rx_ctx(struct qlcnic_cmd_args *cmd)
601 {
602         if ((cmd->req.arg[0] >> 29) != 0x3)
603                 return -EINVAL;
604
605         return 0;
606 }
607
608 static int qlcnic_sriov_pf_create_rx_ctx_cmd(struct qlcnic_bc_trans *tran,
609                                              struct qlcnic_cmd_args *cmd)
610 {
611         struct qlcnic_vf_info *vf = tran->vf;
612         struct qlcnic_adapter *adapter = vf->adapter;
613         struct qlcnic_rcv_mbx_out *mbx_out;
614         int err;
615
616         err = qlcnic_sriov_validate_create_rx_ctx(cmd);
617         if (err) {
618                 cmd->rsp.arg[0] |= (0x6 << 25);
619                 return err;
620         }
621
622         cmd->req.arg[6] = vf->vp->handle;
623         err = qlcnic_issue_cmd(adapter, cmd);
624
625         if (!err) {
626                 mbx_out = (struct qlcnic_rcv_mbx_out *)&cmd->rsp.arg[1];
627                 vf->rx_ctx_id = mbx_out->ctx_id;
628                 qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func,
629                                             0, QLCNIC_MAC_ADD);
630         } else {
631                 vf->rx_ctx_id = 0;
632         }
633
634         return err;
635 }
636
637 static int qlcnic_sriov_pf_mac_address_cmd(struct qlcnic_bc_trans *trans,
638                                            struct qlcnic_cmd_args *cmd)
639 {
640         struct qlcnic_vf_info *vf = trans->vf;
641         u8 type, *mac;
642
643         type = cmd->req.arg[1];
644         switch (type) {
645         case QLCNIC_SET_STATION_MAC:
646         case QLCNIC_SET_FAC_DEF_MAC:
647                 cmd->rsp.arg[0] = (2 << 25);
648                 break;
649         case QLCNIC_GET_CURRENT_MAC:
650                 cmd->rsp.arg[0] = (1 << 25);
651                 mac = vf->vp->mac;
652                 cmd->rsp.arg[2] = mac[1] | ((mac[0] << 8) & 0xff00);
653                 cmd->rsp.arg[1] = mac[5] | ((mac[4] << 8) & 0xff00) |
654                                   ((mac[3]) << 16 & 0xff0000) |
655                                   ((mac[2]) << 24 & 0xff000000);
656         }
657
658         return 0;
659 }
660
661 static int qlcnic_sriov_validate_create_tx_ctx(struct qlcnic_cmd_args *cmd)
662 {
663         if ((cmd->req.arg[0] >> 29) != 0x3)
664                 return -EINVAL;
665
666         return 0;
667 }
668
669 static int qlcnic_sriov_pf_create_tx_ctx_cmd(struct qlcnic_bc_trans *trans,
670                                              struct qlcnic_cmd_args *cmd)
671 {
672         struct qlcnic_vf_info *vf = trans->vf;
673         struct qlcnic_adapter *adapter = vf->adapter;
674         struct qlcnic_tx_mbx_out *mbx_out;
675         int err;
676
677         err = qlcnic_sriov_validate_create_tx_ctx(cmd);
678         if (err) {
679                 cmd->rsp.arg[0] |= (0x6 << 25);
680                 return err;
681         }
682
683         cmd->req.arg[5] |= vf->vp->handle << 16;
684         err = qlcnic_issue_cmd(adapter, cmd);
685         if (!err) {
686                 mbx_out = (struct qlcnic_tx_mbx_out *)&cmd->rsp.arg[2];
687                 vf->tx_ctx_id = mbx_out->ctx_id;
688         } else {
689                 vf->tx_ctx_id = 0;
690         }
691
692         return err;
693 }
694
695 static int qlcnic_sriov_validate_del_rx_ctx(struct qlcnic_vf_info *vf,
696                                             struct qlcnic_cmd_args *cmd)
697 {
698         if ((cmd->req.arg[0] >> 29) != 0x3)
699                 return -EINVAL;
700
701         if ((cmd->req.arg[1] & 0xffff) != vf->rx_ctx_id)
702                 return -EINVAL;
703
704         return 0;
705 }
706
707 static int qlcnic_sriov_pf_del_rx_ctx_cmd(struct qlcnic_bc_trans *trans,
708                                           struct qlcnic_cmd_args *cmd)
709 {
710         struct qlcnic_vf_info *vf = trans->vf;
711         struct qlcnic_adapter *adapter = vf->adapter;
712         int err;
713
714         err = qlcnic_sriov_validate_del_rx_ctx(vf, cmd);
715         if (err) {
716                 cmd->rsp.arg[0] |= (0x6 << 25);
717                 return err;
718         }
719
720         qlcnic_sriov_cfg_vf_def_mac(adapter, vf->vp, vf->pci_func,
721                                     0, QLCNIC_MAC_DEL);
722         cmd->req.arg[1] |= vf->vp->handle << 16;
723         err = qlcnic_issue_cmd(adapter, cmd);
724
725         if (!err)
726                 vf->rx_ctx_id = 0;
727
728         return err;
729 }
730
731 static int qlcnic_sriov_validate_del_tx_ctx(struct qlcnic_vf_info *vf,
732                                             struct qlcnic_cmd_args *cmd)
733 {
734         if ((cmd->req.arg[0] >> 29) != 0x3)
735                 return -EINVAL;
736
737         if ((cmd->req.arg[1] & 0xffff) != vf->tx_ctx_id)
738                 return -EINVAL;
739
740         return 0;
741 }
742
743 static int qlcnic_sriov_pf_del_tx_ctx_cmd(struct qlcnic_bc_trans *trans,
744                                           struct qlcnic_cmd_args *cmd)
745 {
746         struct qlcnic_vf_info *vf = trans->vf;
747         struct qlcnic_adapter *adapter = vf->adapter;
748         int err;
749
750         err = qlcnic_sriov_validate_del_tx_ctx(vf, cmd);
751         if (err) {
752                 cmd->rsp.arg[0] |= (0x6 << 25);
753                 return err;
754         }
755
756         cmd->req.arg[1] |= vf->vp->handle << 16;
757         err = qlcnic_issue_cmd(adapter, cmd);
758
759         if (!err)
760                 vf->tx_ctx_id = 0;
761
762         return err;
763 }
764
765 static int qlcnic_sriov_validate_cfg_lro(struct qlcnic_vf_info *vf,
766                                          struct qlcnic_cmd_args *cmd)
767 {
768         if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
769                 return -EINVAL;
770
771         return 0;
772 }
773
774 static int qlcnic_sriov_pf_cfg_lro_cmd(struct qlcnic_bc_trans *trans,
775                                        struct qlcnic_cmd_args *cmd)
776 {
777         struct qlcnic_vf_info *vf = trans->vf;
778         struct qlcnic_adapter *adapter = vf->adapter;
779         int err;
780
781         err = qlcnic_sriov_validate_cfg_lro(vf, cmd);
782         if (err) {
783                 cmd->rsp.arg[0] |= (0x6 << 25);
784                 return err;
785         }
786
787         err = qlcnic_issue_cmd(adapter, cmd);
788         return err;
789 }
790
791 static int qlcnic_sriov_pf_cfg_ip_cmd(struct qlcnic_bc_trans *trans,
792                                       struct qlcnic_cmd_args *cmd)
793 {
794         struct qlcnic_vf_info *vf = trans->vf;
795         struct qlcnic_adapter *adapter = vf->adapter;
796         int err = -EIO;
797         u8 op;
798
799         op =  cmd->req.arg[1] & 0xff;
800
801         cmd->req.arg[1] |= vf->vp->handle << 16;
802         cmd->req.arg[1] |= BIT_31;
803
804         err = qlcnic_issue_cmd(adapter, cmd);
805         return err;
806 }
807
808 static int qlcnic_sriov_validate_cfg_intrpt(struct qlcnic_vf_info *vf,
809                                             struct qlcnic_cmd_args *cmd)
810 {
811         if (((cmd->req.arg[1] >> 8) & 0xff) != vf->pci_func)
812                 return -EINVAL;
813
814         if (!(cmd->req.arg[1] & BIT_16))
815                 return -EINVAL;
816
817         if ((cmd->req.arg[1] & 0xff) != 0x1)
818                 return -EINVAL;
819
820         return 0;
821 }
822
823 static int qlcnic_sriov_pf_cfg_intrpt_cmd(struct qlcnic_bc_trans *trans,
824                                           struct qlcnic_cmd_args *cmd)
825 {
826         struct qlcnic_vf_info *vf = trans->vf;
827         struct qlcnic_adapter *adapter = vf->adapter;
828         int err;
829
830         err = qlcnic_sriov_validate_cfg_intrpt(vf, cmd);
831         if (err)
832                 cmd->rsp.arg[0] |= (0x6 << 25);
833         else
834                 err = qlcnic_issue_cmd(adapter, cmd);
835
836         return err;
837 }
838
839 static int qlcnic_sriov_validate_mtu(struct qlcnic_adapter *adapter,
840                                      struct qlcnic_vf_info *vf,
841                                      struct qlcnic_cmd_args *cmd)
842 {
843         if (cmd->req.arg[1] != vf->rx_ctx_id)
844                 return -EINVAL;
845
846         if (cmd->req.arg[2] > adapter->ahw->max_mtu)
847                 return -EINVAL;
848
849         return 0;
850 }
851
852 static int qlcnic_sriov_pf_set_mtu_cmd(struct qlcnic_bc_trans *trans,
853                                        struct qlcnic_cmd_args *cmd)
854 {
855         struct qlcnic_vf_info *vf = trans->vf;
856         struct qlcnic_adapter *adapter = vf->adapter;
857         int err;
858
859         err = qlcnic_sriov_validate_mtu(adapter, vf, cmd);
860         if (err)
861                 cmd->rsp.arg[0] |= (0x6 << 25);
862         else
863                 err = qlcnic_issue_cmd(adapter, cmd);
864
865         return err;
866 }
867
868 static int qlcnic_sriov_validate_get_nic_info(struct qlcnic_vf_info *vf,
869                                               struct qlcnic_cmd_args *cmd)
870 {
871         if (cmd->req.arg[1] & BIT_31) {
872                 if (((cmd->req.arg[1] >> 16) & 0x7fff) != vf->pci_func)
873                         return -EINVAL;
874         } else {
875                 cmd->req.arg[1] |= vf->vp->handle << 16;
876         }
877
878         return 0;
879 }
880
881 static int qlcnic_sriov_pf_get_nic_info_cmd(struct qlcnic_bc_trans *trans,
882                                             struct qlcnic_cmd_args *cmd)
883 {
884         struct qlcnic_vf_info *vf = trans->vf;
885         struct qlcnic_adapter *adapter = vf->adapter;
886         int err;
887
888         err = qlcnic_sriov_validate_get_nic_info(vf, cmd);
889         if (err) {
890                 cmd->rsp.arg[0] |= (0x6 << 25);
891                 return err;
892         }
893
894         err = qlcnic_issue_cmd(adapter, cmd);
895         return err;
896 }
897
898 static int qlcnic_sriov_validate_cfg_rss(struct qlcnic_vf_info *vf,
899                                          struct qlcnic_cmd_args *cmd)
900 {
901         if (cmd->req.arg[1] != vf->rx_ctx_id)
902                 return -EINVAL;
903
904         return 0;
905 }
906
907 static int qlcnic_sriov_pf_cfg_rss_cmd(struct qlcnic_bc_trans *trans,
908                                        struct qlcnic_cmd_args *cmd)
909 {
910         struct qlcnic_vf_info *vf = trans->vf;
911         struct qlcnic_adapter *adapter = vf->adapter;
912         int err;
913
914         err = qlcnic_sriov_validate_cfg_rss(vf, cmd);
915         if (err)
916                 cmd->rsp.arg[0] |= (0x6 << 25);
917         else
918                 err = qlcnic_issue_cmd(adapter, cmd);
919
920         return err;
921 }
922
923 static int qlcnic_sriov_validate_cfg_intrcoal(struct qlcnic_adapter *adapter,
924                                               struct qlcnic_vf_info *vf,
925                                               struct qlcnic_cmd_args *cmd)
926 {
927         struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
928         u16 ctx_id, pkts, time;
929
930         ctx_id = cmd->req.arg[1] >> 16;
931         pkts = cmd->req.arg[2] & 0xffff;
932         time = cmd->req.arg[2] >> 16;
933
934         if (ctx_id != vf->rx_ctx_id)
935                 return -EINVAL;
936         if (pkts > coal->rx_packets)
937                 return -EINVAL;
938         if (time < coal->rx_time_us)
939                 return -EINVAL;
940
941         return 0;
942 }
943
944 static int qlcnic_sriov_pf_cfg_intrcoal_cmd(struct qlcnic_bc_trans *tran,
945                                             struct qlcnic_cmd_args *cmd)
946 {
947         struct qlcnic_vf_info *vf = tran->vf;
948         struct qlcnic_adapter *adapter = vf->adapter;
949         int err;
950
951         err = qlcnic_sriov_validate_cfg_intrcoal(adapter, vf, cmd);
952         if (err) {
953                 cmd->rsp.arg[0] |= (0x6 << 25);
954                 return err;
955         }
956
957         err = qlcnic_issue_cmd(adapter, cmd);
958         return err;
959 }
960
961 static int qlcnic_sriov_validate_cfg_macvlan(struct qlcnic_adapter *adapter,
962                                              struct qlcnic_vf_info *vf,
963                                              struct qlcnic_cmd_args *cmd)
964 {
965         struct qlcnic_macvlan_mbx *macvlan;
966
967         if (!(cmd->req.arg[1] & BIT_8))
968                 return -EINVAL;
969
970         cmd->req.arg[1] |= (vf->vp->handle << 16);
971         cmd->req.arg[1] |= BIT_31;
972
973         macvlan = (struct qlcnic_macvlan_mbx *)&cmd->req.arg[2];
974         if (!(macvlan->mac_addr0 & BIT_0)) {
975                 dev_err(&adapter->pdev->dev,
976                         "MAC address change is not allowed from VF %d",
977                         vf->pci_func);
978                 return -EINVAL;
979         }
980
981         return 0;
982 }
983
984 static int qlcnic_sriov_pf_cfg_macvlan_cmd(struct qlcnic_bc_trans *trans,
985                                            struct qlcnic_cmd_args *cmd)
986 {
987         struct qlcnic_vf_info *vf = trans->vf;
988         struct qlcnic_adapter *adapter = vf->adapter;
989         int err;
990
991         err = qlcnic_sriov_validate_cfg_macvlan(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_linkevent(struct qlcnic_vf_info *vf,
1002                                            struct qlcnic_cmd_args *cmd)
1003 {
1004         if ((cmd->req.arg[1] >> 16) != vf->rx_ctx_id)
1005                 return -EINVAL;
1006
1007         if (!(cmd->req.arg[1] & BIT_8))
1008                 return -EINVAL;
1009
1010         return 0;
1011 }
1012
1013 static int qlcnic_sriov_pf_linkevent_cmd(struct qlcnic_bc_trans *trans,
1014                                          struct qlcnic_cmd_args *cmd)
1015 {
1016         struct qlcnic_vf_info *vf = trans->vf;
1017         struct qlcnic_adapter *adapter = vf->adapter;
1018         int err;
1019
1020         err = qlcnic_sriov_validate_linkevent(vf, cmd);
1021         if (err) {
1022                 cmd->rsp.arg[0] |= (0x6 << 25);
1023                 return err;
1024         }
1025
1026         err = qlcnic_issue_cmd(adapter, cmd);
1027         return err;
1028 }
1029
1030 static int qlcnic_sriov_pf_cfg_promisc_cmd(struct qlcnic_bc_trans *trans,
1031                                            struct qlcnic_cmd_args *cmd)
1032 {
1033         struct qlcnic_vf_info *vf = trans->vf;
1034         struct qlcnic_adapter *adapter = vf->adapter;
1035         int err;
1036
1037         cmd->req.arg[1] |= vf->vp->handle << 16;
1038         cmd->req.arg[1] |= BIT_31;
1039         err = qlcnic_issue_cmd(adapter, cmd);
1040         return err;
1041 }
1042
1043 static const int qlcnic_pf_passthru_supp_cmds[] = {
1044         QLCNIC_CMD_GET_STATISTICS,
1045         QLCNIC_CMD_GET_PORT_CONFIG,
1046         QLCNIC_CMD_GET_LINK_STATUS,
1047 };
1048
1049 static const struct qlcnic_sriov_cmd_handler qlcnic_pf_bc_cmd_hdlr[] = {
1050         [QLCNIC_BC_CMD_CHANNEL_INIT] = {&qlcnic_sriov_pf_channel_cfg_cmd},
1051         [QLCNIC_BC_CMD_CHANNEL_TERM] = {&qlcnic_sriov_pf_channel_cfg_cmd},
1052 };
1053
1054 static const struct qlcnic_sriov_fw_cmd_handler qlcnic_pf_fw_cmd_hdlr[] = {
1055         {QLCNIC_CMD_CREATE_RX_CTX, qlcnic_sriov_pf_create_rx_ctx_cmd},
1056         {QLCNIC_CMD_CREATE_TX_CTX, qlcnic_sriov_pf_create_tx_ctx_cmd},
1057         {QLCNIC_CMD_MAC_ADDRESS, qlcnic_sriov_pf_mac_address_cmd},
1058         {QLCNIC_CMD_DESTROY_RX_CTX, qlcnic_sriov_pf_del_rx_ctx_cmd},
1059         {QLCNIC_CMD_DESTROY_TX_CTX, qlcnic_sriov_pf_del_tx_ctx_cmd},
1060         {QLCNIC_CMD_CONFIGURE_HW_LRO, qlcnic_sriov_pf_cfg_lro_cmd},
1061         {QLCNIC_CMD_CONFIGURE_IP_ADDR, qlcnic_sriov_pf_cfg_ip_cmd},
1062         {QLCNIC_CMD_CONFIG_INTRPT, qlcnic_sriov_pf_cfg_intrpt_cmd},
1063         {QLCNIC_CMD_SET_MTU, qlcnic_sriov_pf_set_mtu_cmd},
1064         {QLCNIC_CMD_GET_NIC_INFO, qlcnic_sriov_pf_get_nic_info_cmd},
1065         {QLCNIC_CMD_CONFIGURE_RSS, qlcnic_sriov_pf_cfg_rss_cmd},
1066         {QLCNIC_CMD_CONFIG_INTR_COAL, qlcnic_sriov_pf_cfg_intrcoal_cmd},
1067         {QLCNIC_CMD_CONFIG_MAC_VLAN, qlcnic_sriov_pf_cfg_macvlan_cmd},
1068         {QLCNIC_CMD_GET_LINK_EVENT, qlcnic_sriov_pf_linkevent_cmd},
1069         {QLCNIC_CMD_CONFIGURE_MAC_RX_MODE, qlcnic_sriov_pf_cfg_promisc_cmd},
1070 };
1071
1072 void qlcnic_sriov_pf_process_bc_cmd(struct qlcnic_adapter *adapter,
1073                                     struct qlcnic_bc_trans *trans,
1074                                     struct qlcnic_cmd_args *cmd)
1075 {
1076         u8 size, cmd_op;
1077
1078         cmd_op = trans->req_hdr->cmd_op;
1079
1080         if (trans->req_hdr->op_type == QLC_BC_CMD) {
1081                 size = ARRAY_SIZE(qlcnic_pf_bc_cmd_hdlr);
1082                 if (cmd_op < size) {
1083                         qlcnic_pf_bc_cmd_hdlr[cmd_op].fn(trans, cmd);
1084                         return;
1085                 }
1086         } else {
1087                 int i;
1088                 size = ARRAY_SIZE(qlcnic_pf_fw_cmd_hdlr);
1089                 for (i = 0; i < size; i++) {
1090                         if (cmd_op == qlcnic_pf_fw_cmd_hdlr[i].cmd) {
1091                                 qlcnic_pf_fw_cmd_hdlr[i].fn(trans, cmd);
1092                                 return;
1093                         }
1094                 }
1095
1096                 size = ARRAY_SIZE(qlcnic_pf_passthru_supp_cmds);
1097                 for (i = 0; i < size; i++) {
1098                         if (cmd_op == qlcnic_pf_passthru_supp_cmds[i]) {
1099                                 qlcnic_issue_cmd(adapter, cmd);
1100                                 return;
1101                         }
1102                 }
1103         }
1104
1105         cmd->rsp.arg[0] |= (0x9 << 25);
1106 }
1107
1108 void qlcnic_pf_set_interface_id_create_rx_ctx(struct qlcnic_adapter *adapter,
1109                                              u32 *int_id)
1110 {
1111         u16 vpid;
1112
1113         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1114                                                 adapter->ahw->pci_func);
1115         *int_id |= vpid;
1116 }
1117
1118 void qlcnic_pf_set_interface_id_del_rx_ctx(struct qlcnic_adapter *adapter,
1119                                            u32 *int_id)
1120 {
1121         u16 vpid;
1122
1123         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1124                                                 adapter->ahw->pci_func);
1125         *int_id |= vpid << 16;
1126 }
1127
1128 void qlcnic_pf_set_interface_id_create_tx_ctx(struct qlcnic_adapter *adapter,
1129                                               u32 *int_id)
1130 {
1131         int vpid;
1132
1133         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1134                                                 adapter->ahw->pci_func);
1135         *int_id |= vpid << 16;
1136 }
1137
1138 void qlcnic_pf_set_interface_id_del_tx_ctx(struct qlcnic_adapter *adapter,
1139                                            u32 *int_id)
1140 {
1141         u16 vpid;
1142
1143         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1144                                                 adapter->ahw->pci_func);
1145         *int_id |= vpid << 16;
1146 }
1147
1148 void qlcnic_pf_set_interface_id_promisc(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 << 16) | BIT_31;
1156 }
1157
1158 void qlcnic_pf_set_interface_id_ipaddr(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) | BIT_31;
1166 }
1167
1168 void qlcnic_pf_set_interface_id_macaddr(struct qlcnic_adapter *adapter,
1169                                         u32 *int_id)
1170 {
1171         u16 vpid;
1172
1173         vpid = qlcnic_sriov_pf_get_vport_handle(adapter,
1174                                                 adapter->ahw->pci_func);
1175         *int_id |= (vpid << 16) | BIT_31;
1176 }