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