.. | .. |
---|
33 | 33 | |
---|
34 | 34 | static int lio_reset_queues(struct net_device *netdev, uint32_t num_qs); |
---|
35 | 35 | |
---|
36 | | -struct oct_intrmod_context { |
---|
37 | | - int octeon_id; |
---|
38 | | - wait_queue_head_t wc; |
---|
39 | | - int cond; |
---|
40 | | - int status; |
---|
41 | | -}; |
---|
42 | | - |
---|
43 | 36 | struct oct_intrmod_resp { |
---|
44 | 37 | u64 rh; |
---|
45 | 38 | struct oct_intrmod_cfg intrmod; |
---|
46 | 39 | u64 status; |
---|
47 | | -}; |
---|
48 | | - |
---|
49 | | -struct oct_mdio_cmd_context { |
---|
50 | | - int octeon_id; |
---|
51 | | - wait_queue_head_t wc; |
---|
52 | | - int cond; |
---|
53 | 40 | }; |
---|
54 | 41 | |
---|
55 | 42 | struct oct_mdio_cmd_resp { |
---|
.. | .. |
---|
124 | 111 | "mac_tx_one_collision", |
---|
125 | 112 | "mac_tx_multi_collision", |
---|
126 | 113 | "mac_tx_max_collision_fail", |
---|
127 | | - "mac_tx_max_deferal_fail", |
---|
| 114 | + "mac_tx_max_deferral_fail", |
---|
128 | 115 | "mac_tx_fifo_err", |
---|
129 | 116 | "mac_tx_runts", |
---|
130 | 117 | |
---|
.. | .. |
---|
257 | 244 | linfo->link.s.if_mode == INTERFACE_MODE_XLAUI || |
---|
258 | 245 | linfo->link.s.if_mode == INTERFACE_MODE_XFI) { |
---|
259 | 246 | dev_dbg(&oct->pci_dev->dev, "ecmd->base.transceiver is XCVR_EXTERNAL\n"); |
---|
| 247 | + ecmd->base.transceiver = XCVR_EXTERNAL; |
---|
260 | 248 | } else { |
---|
261 | 249 | dev_err(&oct->pci_dev->dev, "Unknown link interface mode: %d\n", |
---|
262 | 250 | linfo->link.s.if_mode); |
---|
.. | .. |
---|
290 | 278 | 10000baseCR_Full); |
---|
291 | 279 | } |
---|
292 | 280 | |
---|
293 | | - if (oct->no_speed_setting == 0) |
---|
| 281 | + if (oct->no_speed_setting == 0) { |
---|
294 | 282 | liquidio_get_speed(lio); |
---|
295 | | - else |
---|
| 283 | + liquidio_get_fec(lio); |
---|
| 284 | + } else { |
---|
296 | 285 | oct->speed_setting = 25; |
---|
| 286 | + } |
---|
297 | 287 | |
---|
298 | 288 | if (oct->speed_setting == 10) { |
---|
299 | 289 | ethtool_link_ksettings_add_link_mode |
---|
.. | .. |
---|
316 | 306 | ethtool_link_ksettings_add_link_mode |
---|
317 | 307 | (ecmd, advertising, |
---|
318 | 308 | 25000baseCR_Full); |
---|
| 309 | + } |
---|
| 310 | + |
---|
| 311 | + if (oct->no_speed_setting) |
---|
| 312 | + break; |
---|
| 313 | + |
---|
| 314 | + ethtool_link_ksettings_add_link_mode |
---|
| 315 | + (ecmd, supported, FEC_RS); |
---|
| 316 | + ethtool_link_ksettings_add_link_mode |
---|
| 317 | + (ecmd, supported, FEC_NONE); |
---|
| 318 | + /*FEC_OFF*/ |
---|
| 319 | + if (oct->props[lio->ifidx].fec == 1) { |
---|
| 320 | + /* ETHTOOL_FEC_RS */ |
---|
| 321 | + ethtool_link_ksettings_add_link_mode |
---|
| 322 | + (ecmd, advertising, FEC_RS); |
---|
| 323 | + } else { |
---|
| 324 | + /* ETHTOOL_FEC_OFF */ |
---|
| 325 | + ethtool_link_ksettings_add_link_mode |
---|
| 326 | + (ecmd, advertising, FEC_NONE); |
---|
319 | 327 | } |
---|
320 | 328 | } else { /* VF */ |
---|
321 | 329 | if (linfo->link.s.speed == 10000) { |
---|
.. | .. |
---|
434 | 442 | |
---|
435 | 443 | memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); |
---|
436 | 444 | strcpy(drvinfo->driver, "liquidio"); |
---|
437 | | - strcpy(drvinfo->version, LIQUIDIO_VERSION); |
---|
438 | 445 | strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version, |
---|
439 | 446 | ETHTOOL_FWVERS_LEN); |
---|
440 | 447 | strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32); |
---|
.. | .. |
---|
451 | 458 | |
---|
452 | 459 | memset(drvinfo, 0, sizeof(struct ethtool_drvinfo)); |
---|
453 | 460 | strcpy(drvinfo->driver, "liquidio_vf"); |
---|
454 | | - strcpy(drvinfo->version, LIQUIDIO_VERSION); |
---|
455 | 461 | strncpy(drvinfo->fw_version, oct->fw_info.liquidio_firmware_version, |
---|
456 | 462 | ETHTOOL_FWVERS_LEN); |
---|
457 | 463 | strncpy(drvinfo->bus_info, pci_name(oct->pci_dev), 32); |
---|
.. | .. |
---|
472 | 478 | nctrl.ncmd.s.param1 = num_queues; |
---|
473 | 479 | nctrl.ncmd.s.param2 = num_queues; |
---|
474 | 480 | nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; |
---|
475 | | - nctrl.wait_time = 100; |
---|
476 | 481 | nctrl.netpndev = (u64)netdev; |
---|
477 | 482 | nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; |
---|
478 | 483 | |
---|
479 | 484 | ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); |
---|
480 | | - if (ret < 0) { |
---|
| 485 | + if (ret) { |
---|
481 | 486 | dev_err(&oct->pci_dev->dev, "Failed to send Queue reset command (ret: 0x%x)\n", |
---|
482 | 487 | ret); |
---|
483 | 488 | return -1; |
---|
.. | .. |
---|
708 | 713 | nctrl.ncmd.s.param1 = addr; |
---|
709 | 714 | nctrl.ncmd.s.param2 = val; |
---|
710 | 715 | nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; |
---|
711 | | - nctrl.wait_time = 100; |
---|
712 | 716 | nctrl.netpndev = (u64)netdev; |
---|
713 | 717 | nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; |
---|
714 | 718 | |
---|
715 | 719 | ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); |
---|
716 | | - if (ret < 0) { |
---|
717 | | - dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n"); |
---|
| 720 | + if (ret) { |
---|
| 721 | + dev_err(&oct->pci_dev->dev, |
---|
| 722 | + "Failed to configure gpio value, ret=%d\n", ret); |
---|
718 | 723 | return -EINVAL; |
---|
719 | 724 | } |
---|
720 | 725 | |
---|
.. | .. |
---|
734 | 739 | nctrl.ncmd.s.cmd = OCTNET_CMD_ID_ACTIVE; |
---|
735 | 740 | nctrl.ncmd.s.param1 = val; |
---|
736 | 741 | nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; |
---|
737 | | - nctrl.wait_time = 100; |
---|
738 | 742 | nctrl.netpndev = (u64)netdev; |
---|
739 | 743 | nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; |
---|
740 | 744 | |
---|
741 | 745 | ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); |
---|
742 | | - if (ret < 0) { |
---|
743 | | - dev_err(&oct->pci_dev->dev, "Failed to configure gpio value\n"); |
---|
| 746 | + if (ret) { |
---|
| 747 | + dev_err(&oct->pci_dev->dev, |
---|
| 748 | + "Failed to configure gpio value, ret=%d\n", ret); |
---|
744 | 749 | return -EINVAL; |
---|
745 | 750 | } |
---|
746 | 751 | |
---|
747 | 752 | return 0; |
---|
748 | | -} |
---|
749 | | - |
---|
750 | | -/* Callback for when mdio command response arrives |
---|
751 | | - */ |
---|
752 | | -static void octnet_mdio_resp_callback(struct octeon_device *oct, |
---|
753 | | - u32 status, |
---|
754 | | - void *buf) |
---|
755 | | -{ |
---|
756 | | - struct oct_mdio_cmd_context *mdio_cmd_ctx; |
---|
757 | | - struct octeon_soft_command *sc = (struct octeon_soft_command *)buf; |
---|
758 | | - |
---|
759 | | - mdio_cmd_ctx = (struct oct_mdio_cmd_context *)sc->ctxptr; |
---|
760 | | - |
---|
761 | | - oct = lio_get_device(mdio_cmd_ctx->octeon_id); |
---|
762 | | - if (status) { |
---|
763 | | - dev_err(&oct->pci_dev->dev, "MIDO instruction failed. Status: %llx\n", |
---|
764 | | - CVM_CAST64(status)); |
---|
765 | | - WRITE_ONCE(mdio_cmd_ctx->cond, -1); |
---|
766 | | - } else { |
---|
767 | | - WRITE_ONCE(mdio_cmd_ctx->cond, 1); |
---|
768 | | - } |
---|
769 | | - wake_up_interruptible(&mdio_cmd_ctx->wc); |
---|
770 | 753 | } |
---|
771 | 754 | |
---|
772 | 755 | /* This routine provides PHY access routines for |
---|
.. | .. |
---|
778 | 761 | struct octeon_device *oct_dev = lio->oct_dev; |
---|
779 | 762 | struct octeon_soft_command *sc; |
---|
780 | 763 | struct oct_mdio_cmd_resp *mdio_cmd_rsp; |
---|
781 | | - struct oct_mdio_cmd_context *mdio_cmd_ctx; |
---|
782 | 764 | struct oct_mdio_cmd *mdio_cmd; |
---|
783 | 765 | int retval = 0; |
---|
784 | 766 | |
---|
785 | 767 | sc = (struct octeon_soft_command *) |
---|
786 | 768 | octeon_alloc_soft_command(oct_dev, |
---|
787 | 769 | sizeof(struct oct_mdio_cmd), |
---|
788 | | - sizeof(struct oct_mdio_cmd_resp), |
---|
789 | | - sizeof(struct oct_mdio_cmd_context)); |
---|
| 770 | + sizeof(struct oct_mdio_cmd_resp), 0); |
---|
790 | 771 | |
---|
791 | 772 | if (!sc) |
---|
792 | 773 | return -ENOMEM; |
---|
793 | 774 | |
---|
794 | | - mdio_cmd_ctx = (struct oct_mdio_cmd_context *)sc->ctxptr; |
---|
795 | 775 | mdio_cmd_rsp = (struct oct_mdio_cmd_resp *)sc->virtrptr; |
---|
796 | 776 | mdio_cmd = (struct oct_mdio_cmd *)sc->virtdptr; |
---|
797 | 777 | |
---|
798 | | - WRITE_ONCE(mdio_cmd_ctx->cond, 0); |
---|
799 | | - mdio_cmd_ctx->octeon_id = lio_get_device_id(oct_dev); |
---|
800 | 778 | mdio_cmd->op = op; |
---|
801 | 779 | mdio_cmd->mdio_addr = loc; |
---|
802 | 780 | if (op) |
---|
.. | .. |
---|
808 | 786 | octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, OPCODE_NIC_MDIO45, |
---|
809 | 787 | 0, 0, 0); |
---|
810 | 788 | |
---|
811 | | - sc->wait_time = 1000; |
---|
812 | | - sc->callback = octnet_mdio_resp_callback; |
---|
813 | | - sc->callback_arg = sc; |
---|
814 | | - |
---|
815 | | - init_waitqueue_head(&mdio_cmd_ctx->wc); |
---|
| 789 | + init_completion(&sc->complete); |
---|
| 790 | + sc->sc_status = OCTEON_REQUEST_PENDING; |
---|
816 | 791 | |
---|
817 | 792 | retval = octeon_send_soft_command(oct_dev, sc); |
---|
818 | | - |
---|
819 | 793 | if (retval == IQ_SEND_FAILED) { |
---|
820 | 794 | dev_err(&oct_dev->pci_dev->dev, |
---|
821 | 795 | "octnet_mdio45_access instruction failed status: %x\n", |
---|
822 | 796 | retval); |
---|
823 | | - retval = -EBUSY; |
---|
| 797 | + octeon_free_soft_command(oct_dev, sc); |
---|
| 798 | + return -EBUSY; |
---|
824 | 799 | } else { |
---|
825 | 800 | /* Sleep on a wait queue till the cond flag indicates that the |
---|
826 | 801 | * response arrived |
---|
827 | 802 | */ |
---|
828 | | - sleep_cond(&mdio_cmd_ctx->wc, &mdio_cmd_ctx->cond); |
---|
| 803 | + retval = wait_for_sc_completion_timeout(oct_dev, sc, 0); |
---|
| 804 | + if (retval) |
---|
| 805 | + return retval; |
---|
| 806 | + |
---|
829 | 807 | retval = mdio_cmd_rsp->status; |
---|
830 | 808 | if (retval) { |
---|
831 | | - dev_err(&oct_dev->pci_dev->dev, "octnet mdio45 access failed\n"); |
---|
832 | | - retval = -EBUSY; |
---|
833 | | - } else { |
---|
834 | | - octeon_swap_8B_data((u64 *)(&mdio_cmd_rsp->resp), |
---|
835 | | - sizeof(struct oct_mdio_cmd) / 8); |
---|
836 | | - |
---|
837 | | - if (READ_ONCE(mdio_cmd_ctx->cond) == 1) { |
---|
838 | | - if (!op) |
---|
839 | | - *value = mdio_cmd_rsp->resp.value1; |
---|
840 | | - } else { |
---|
841 | | - retval = -EINVAL; |
---|
842 | | - } |
---|
| 809 | + dev_err(&oct_dev->pci_dev->dev, |
---|
| 810 | + "octnet mdio45 access failed: %x\n", retval); |
---|
| 811 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 812 | + return -EBUSY; |
---|
843 | 813 | } |
---|
844 | | - } |
---|
845 | 814 | |
---|
846 | | - octeon_free_soft_command(oct_dev, sc); |
---|
| 815 | + octeon_swap_8B_data((u64 *)(&mdio_cmd_rsp->resp), |
---|
| 816 | + sizeof(struct oct_mdio_cmd) / 8); |
---|
| 817 | + |
---|
| 818 | + if (!op) |
---|
| 819 | + *value = mdio_cmd_rsp->resp.value1; |
---|
| 820 | + |
---|
| 821 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 822 | + } |
---|
847 | 823 | |
---|
848 | 824 | return retval; |
---|
849 | 825 | } |
---|
.. | .. |
---|
1007 | 983 | static int lio_23xx_reconfigure_queue_count(struct lio *lio) |
---|
1008 | 984 | { |
---|
1009 | 985 | struct octeon_device *oct = lio->oct_dev; |
---|
1010 | | - struct liquidio_if_cfg_context *ctx; |
---|
1011 | | - u32 resp_size, ctx_size, data_size; |
---|
| 986 | + u32 resp_size, data_size; |
---|
1012 | 987 | struct liquidio_if_cfg_resp *resp; |
---|
1013 | 988 | struct octeon_soft_command *sc; |
---|
1014 | 989 | union oct_nic_if_cfg if_cfg; |
---|
.. | .. |
---|
1018 | 993 | int j; |
---|
1019 | 994 | |
---|
1020 | 995 | resp_size = sizeof(struct liquidio_if_cfg_resp); |
---|
1021 | | - ctx_size = sizeof(struct liquidio_if_cfg_context); |
---|
1022 | 996 | data_size = sizeof(struct lio_version); |
---|
1023 | 997 | sc = (struct octeon_soft_command *) |
---|
1024 | 998 | octeon_alloc_soft_command(oct, data_size, |
---|
1025 | | - resp_size, ctx_size); |
---|
| 999 | + resp_size, 0); |
---|
1026 | 1000 | if (!sc) { |
---|
1027 | 1001 | dev_err(&oct->pci_dev->dev, "%s: Failed to allocate soft command\n", |
---|
1028 | 1002 | __func__); |
---|
.. | .. |
---|
1030 | 1004 | } |
---|
1031 | 1005 | |
---|
1032 | 1006 | resp = (struct liquidio_if_cfg_resp *)sc->virtrptr; |
---|
1033 | | - ctx = (struct liquidio_if_cfg_context *)sc->ctxptr; |
---|
1034 | 1007 | vdata = (struct lio_version *)sc->virtdptr; |
---|
1035 | 1008 | |
---|
1036 | 1009 | vdata->major = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MAJOR_VERSION); |
---|
.. | .. |
---|
1038 | 1011 | vdata->micro = (__force u16)cpu_to_be16(LIQUIDIO_BASE_MICRO_VERSION); |
---|
1039 | 1012 | |
---|
1040 | 1013 | ifidx_or_pfnum = oct->pf_num; |
---|
1041 | | - WRITE_ONCE(ctx->cond, 0); |
---|
1042 | | - ctx->octeon_id = lio_get_device_id(oct); |
---|
1043 | | - init_waitqueue_head(&ctx->wc); |
---|
1044 | 1014 | |
---|
1045 | 1015 | if_cfg.u64 = 0; |
---|
1046 | 1016 | if_cfg.s.num_iqueues = oct->sriov_info.num_pf_rings; |
---|
.. | .. |
---|
1052 | 1022 | octeon_prepare_soft_command(oct, sc, OPCODE_NIC, |
---|
1053 | 1023 | OPCODE_NIC_QCOUNT_UPDATE, 0, |
---|
1054 | 1024 | if_cfg.u64, 0); |
---|
1055 | | - sc->callback = lio_if_cfg_callback; |
---|
1056 | | - sc->callback_arg = sc; |
---|
1057 | | - sc->wait_time = LIO_IFCFG_WAIT_TIME; |
---|
| 1025 | + |
---|
| 1026 | + init_completion(&sc->complete); |
---|
| 1027 | + sc->sc_status = OCTEON_REQUEST_PENDING; |
---|
1058 | 1028 | |
---|
1059 | 1029 | retval = octeon_send_soft_command(oct, sc); |
---|
1060 | 1030 | if (retval == IQ_SEND_FAILED) { |
---|
1061 | 1031 | dev_err(&oct->pci_dev->dev, |
---|
1062 | | - "iq/oq config failed status: %x\n", |
---|
| 1032 | + "Sending iq/oq config failed status: %x\n", |
---|
1063 | 1033 | retval); |
---|
1064 | | - goto qcount_update_fail; |
---|
| 1034 | + octeon_free_soft_command(oct, sc); |
---|
| 1035 | + return -EIO; |
---|
1065 | 1036 | } |
---|
1066 | 1037 | |
---|
1067 | | - if (sleep_cond(&ctx->wc, &ctx->cond) == -EINTR) { |
---|
1068 | | - dev_err(&oct->pci_dev->dev, "Wait interrupted\n"); |
---|
1069 | | - return -1; |
---|
1070 | | - } |
---|
| 1038 | + retval = wait_for_sc_completion_timeout(oct, sc, 0); |
---|
| 1039 | + if (retval) |
---|
| 1040 | + return retval; |
---|
1071 | 1041 | |
---|
1072 | 1042 | retval = resp->status; |
---|
1073 | 1043 | if (retval) { |
---|
1074 | | - dev_err(&oct->pci_dev->dev, "iq/oq config failed\n"); |
---|
1075 | | - goto qcount_update_fail; |
---|
| 1044 | + dev_err(&oct->pci_dev->dev, |
---|
| 1045 | + "iq/oq config failed: %x\n", retval); |
---|
| 1046 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 1047 | + return -1; |
---|
1076 | 1048 | } |
---|
1077 | 1049 | |
---|
1078 | 1050 | octeon_swap_8B_data((u64 *)(&resp->cfg_info), |
---|
.. | .. |
---|
1097 | 1069 | lio->txq = lio->linfo.txpciq[0].s.q_no; |
---|
1098 | 1070 | lio->rxq = lio->linfo.rxpciq[0].s.q_no; |
---|
1099 | 1071 | |
---|
1100 | | - octeon_free_soft_command(oct, sc); |
---|
1101 | 1072 | dev_info(&oct->pci_dev->dev, "Queue count updated to %d\n", |
---|
1102 | 1073 | lio->linfo.num_rxpciq); |
---|
1103 | 1074 | |
---|
| 1075 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 1076 | + |
---|
1104 | 1077 | return 0; |
---|
1105 | | - |
---|
1106 | | -qcount_update_fail: |
---|
1107 | | - octeon_free_soft_command(oct, sc); |
---|
1108 | | - |
---|
1109 | | - return -1; |
---|
1110 | 1078 | } |
---|
1111 | 1079 | |
---|
1112 | 1080 | static int lio_reset_queues(struct net_device *netdev, uint32_t num_qs) |
---|
.. | .. |
---|
1166 | 1134 | * steps like updating sriov_info for the octeon device need to be done. |
---|
1167 | 1135 | */ |
---|
1168 | 1136 | if (queue_count_update) { |
---|
| 1137 | + cleanup_rx_oom_poll_fn(netdev); |
---|
| 1138 | + |
---|
1169 | 1139 | lio_delete_glists(lio); |
---|
1170 | 1140 | |
---|
1171 | 1141 | /* Delete mbox for PF which is SRIOV disabled because sriov_info |
---|
.. | .. |
---|
1263 | 1233 | if (lio_setup_glists(oct, lio, num_qs)) { |
---|
1264 | 1234 | dev_err(&oct->pci_dev->dev, "Gather list allocation failed\n"); |
---|
1265 | 1235 | return -1; |
---|
| 1236 | + } |
---|
| 1237 | + |
---|
| 1238 | + if (setup_rx_oom_poll_fn(netdev)) { |
---|
| 1239 | + dev_err(&oct->pci_dev->dev, "lio_setup_rx_oom_poll_fn failed\n"); |
---|
| 1240 | + return 1; |
---|
1266 | 1241 | } |
---|
1267 | 1242 | |
---|
1268 | 1243 | /* Send firmware the information about new number of queues |
---|
.. | .. |
---|
1412 | 1387 | nctrl.ncmd.u64 = 0; |
---|
1413 | 1388 | nctrl.ncmd.s.cmd = OCTNET_CMD_SET_FLOW_CTL; |
---|
1414 | 1389 | nctrl.iq_no = lio->linfo.txpciq[0].s.q_no; |
---|
1415 | | - nctrl.wait_time = 100; |
---|
1416 | 1390 | nctrl.netpndev = (u64)netdev; |
---|
1417 | 1391 | nctrl.cb_fn = liquidio_link_ctrl_cmd_completion; |
---|
1418 | 1392 | |
---|
.. | .. |
---|
1433 | 1407 | } |
---|
1434 | 1408 | |
---|
1435 | 1409 | ret = octnet_send_nic_ctrl_pkt(lio->oct_dev, &nctrl); |
---|
1436 | | - if (ret < 0) { |
---|
1437 | | - dev_err(&oct->pci_dev->dev, "Failed to set pause parameter\n"); |
---|
| 1410 | + if (ret) { |
---|
| 1411 | + dev_err(&oct->pci_dev->dev, |
---|
| 1412 | + "Failed to set pause parameter, ret=%d\n", ret); |
---|
1438 | 1413 | return -EINVAL; |
---|
1439 | 1414 | } |
---|
1440 | 1415 | |
---|
.. | .. |
---|
1764 | 1739 | */ |
---|
1765 | 1740 | data[i++] = lstats.rx_dropped; |
---|
1766 | 1741 | /* sum of oct->instr_queue[iq_no]->stats.tx_dropped */ |
---|
1767 | | - data[i++] = lstats.tx_dropped; |
---|
| 1742 | + data[i++] = lstats.tx_dropped + |
---|
| 1743 | + oct_dev->link_stats.fromhost.fw_err_drop; |
---|
1768 | 1744 | |
---|
1769 | 1745 | data[i++] = oct_dev->link_stats.fromwire.fw_total_mcast; |
---|
1770 | 1746 | data[i++] = oct_dev->link_stats.fromhost.fw_total_mcast_sent; |
---|
.. | .. |
---|
2013 | 1989 | } |
---|
2014 | 1990 | } |
---|
2015 | 1991 | |
---|
2016 | | -/* Callback function for intrmod */ |
---|
2017 | | -static void octnet_intrmod_callback(struct octeon_device *oct_dev, |
---|
2018 | | - u32 status, |
---|
2019 | | - void *ptr) |
---|
2020 | | -{ |
---|
2021 | | - struct octeon_soft_command *sc = (struct octeon_soft_command *)ptr; |
---|
2022 | | - struct oct_intrmod_context *ctx; |
---|
2023 | | - |
---|
2024 | | - ctx = (struct oct_intrmod_context *)sc->ctxptr; |
---|
2025 | | - |
---|
2026 | | - ctx->status = status; |
---|
2027 | | - |
---|
2028 | | - WRITE_ONCE(ctx->cond, 1); |
---|
2029 | | - |
---|
2030 | | - /* This barrier is required to be sure that the response has been |
---|
2031 | | - * written fully before waking up the handler |
---|
2032 | | - */ |
---|
2033 | | - wmb(); |
---|
2034 | | - |
---|
2035 | | - wake_up_interruptible(&ctx->wc); |
---|
2036 | | -} |
---|
2037 | | - |
---|
2038 | 1992 | /* get interrupt moderation parameters */ |
---|
2039 | 1993 | static int octnet_get_intrmod_cfg(struct lio *lio, |
---|
2040 | 1994 | struct oct_intrmod_cfg *intr_cfg) |
---|
2041 | 1995 | { |
---|
2042 | 1996 | struct octeon_soft_command *sc; |
---|
2043 | | - struct oct_intrmod_context *ctx; |
---|
2044 | 1997 | struct oct_intrmod_resp *resp; |
---|
2045 | 1998 | int retval; |
---|
2046 | 1999 | struct octeon_device *oct_dev = lio->oct_dev; |
---|
.. | .. |
---|
2049 | 2002 | sc = (struct octeon_soft_command *) |
---|
2050 | 2003 | octeon_alloc_soft_command(oct_dev, |
---|
2051 | 2004 | 0, |
---|
2052 | | - sizeof(struct oct_intrmod_resp), |
---|
2053 | | - sizeof(struct oct_intrmod_context)); |
---|
| 2005 | + sizeof(struct oct_intrmod_resp), 0); |
---|
2054 | 2006 | |
---|
2055 | 2007 | if (!sc) |
---|
2056 | 2008 | return -ENOMEM; |
---|
.. | .. |
---|
2058 | 2010 | resp = (struct oct_intrmod_resp *)sc->virtrptr; |
---|
2059 | 2011 | memset(resp, 0, sizeof(struct oct_intrmod_resp)); |
---|
2060 | 2012 | |
---|
2061 | | - ctx = (struct oct_intrmod_context *)sc->ctxptr; |
---|
2062 | | - memset(ctx, 0, sizeof(struct oct_intrmod_context)); |
---|
2063 | | - WRITE_ONCE(ctx->cond, 0); |
---|
2064 | | - ctx->octeon_id = lio_get_device_id(oct_dev); |
---|
2065 | | - init_waitqueue_head(&ctx->wc); |
---|
2066 | | - |
---|
2067 | 2013 | sc->iq_no = lio->linfo.txpciq[0].s.q_no; |
---|
2068 | 2014 | |
---|
2069 | 2015 | octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, |
---|
2070 | 2016 | OPCODE_NIC_INTRMOD_PARAMS, 0, 0, 0); |
---|
2071 | 2017 | |
---|
2072 | | - sc->callback = octnet_intrmod_callback; |
---|
2073 | | - sc->callback_arg = sc; |
---|
2074 | | - sc->wait_time = 1000; |
---|
| 2018 | + init_completion(&sc->complete); |
---|
| 2019 | + sc->sc_status = OCTEON_REQUEST_PENDING; |
---|
2075 | 2020 | |
---|
2076 | 2021 | retval = octeon_send_soft_command(oct_dev, sc); |
---|
2077 | 2022 | if (retval == IQ_SEND_FAILED) { |
---|
.. | .. |
---|
2082 | 2027 | /* Sleep on a wait queue till the cond flag indicates that the |
---|
2083 | 2028 | * response arrived or timed-out. |
---|
2084 | 2029 | */ |
---|
2085 | | - if (sleep_cond(&ctx->wc, &ctx->cond) == -EINTR) { |
---|
2086 | | - dev_err(&oct_dev->pci_dev->dev, "Wait interrupted\n"); |
---|
2087 | | - goto intrmod_info_wait_intr; |
---|
2088 | | - } |
---|
| 2030 | + retval = wait_for_sc_completion_timeout(oct_dev, sc, 0); |
---|
| 2031 | + if (retval) |
---|
| 2032 | + return -ENODEV; |
---|
2089 | 2033 | |
---|
2090 | | - retval = ctx->status || resp->status; |
---|
2091 | | - if (retval) { |
---|
| 2034 | + if (resp->status) { |
---|
2092 | 2035 | dev_err(&oct_dev->pci_dev->dev, |
---|
2093 | 2036 | "Get interrupt moderation parameters failed\n"); |
---|
2094 | | - goto intrmod_info_wait_fail; |
---|
| 2037 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 2038 | + return -ENODEV; |
---|
2095 | 2039 | } |
---|
2096 | 2040 | |
---|
2097 | 2041 | octeon_swap_8B_data((u64 *)&resp->intrmod, |
---|
2098 | 2042 | (sizeof(struct oct_intrmod_cfg)) / 8); |
---|
2099 | 2043 | memcpy(intr_cfg, &resp->intrmod, sizeof(struct oct_intrmod_cfg)); |
---|
2100 | | - octeon_free_soft_command(oct_dev, sc); |
---|
| 2044 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
2101 | 2045 | |
---|
2102 | 2046 | return 0; |
---|
2103 | | - |
---|
2104 | | -intrmod_info_wait_fail: |
---|
2105 | | - |
---|
2106 | | - octeon_free_soft_command(oct_dev, sc); |
---|
2107 | | - |
---|
2108 | | -intrmod_info_wait_intr: |
---|
2109 | | - |
---|
2110 | | - return -ENODEV; |
---|
2111 | 2047 | } |
---|
2112 | 2048 | |
---|
2113 | 2049 | /* Configure interrupt moderation parameters */ |
---|
.. | .. |
---|
2115 | 2051 | struct oct_intrmod_cfg *intr_cfg) |
---|
2116 | 2052 | { |
---|
2117 | 2053 | struct octeon_soft_command *sc; |
---|
2118 | | - struct oct_intrmod_context *ctx; |
---|
2119 | 2054 | struct oct_intrmod_cfg *cfg; |
---|
2120 | 2055 | int retval; |
---|
2121 | 2056 | struct octeon_device *oct_dev = lio->oct_dev; |
---|
.. | .. |
---|
2124 | 2059 | sc = (struct octeon_soft_command *) |
---|
2125 | 2060 | octeon_alloc_soft_command(oct_dev, |
---|
2126 | 2061 | sizeof(struct oct_intrmod_cfg), |
---|
2127 | | - 0, |
---|
2128 | | - sizeof(struct oct_intrmod_context)); |
---|
| 2062 | + 16, 0); |
---|
2129 | 2063 | |
---|
2130 | 2064 | if (!sc) |
---|
2131 | 2065 | return -ENOMEM; |
---|
2132 | | - |
---|
2133 | | - ctx = (struct oct_intrmod_context *)sc->ctxptr; |
---|
2134 | | - |
---|
2135 | | - WRITE_ONCE(ctx->cond, 0); |
---|
2136 | | - ctx->octeon_id = lio_get_device_id(oct_dev); |
---|
2137 | | - init_waitqueue_head(&ctx->wc); |
---|
2138 | 2066 | |
---|
2139 | 2067 | cfg = (struct oct_intrmod_cfg *)sc->virtdptr; |
---|
2140 | 2068 | |
---|
.. | .. |
---|
2146 | 2074 | octeon_prepare_soft_command(oct_dev, sc, OPCODE_NIC, |
---|
2147 | 2075 | OPCODE_NIC_INTRMOD_CFG, 0, 0, 0); |
---|
2148 | 2076 | |
---|
2149 | | - sc->callback = octnet_intrmod_callback; |
---|
2150 | | - sc->callback_arg = sc; |
---|
2151 | | - sc->wait_time = 1000; |
---|
| 2077 | + init_completion(&sc->complete); |
---|
| 2078 | + sc->sc_status = OCTEON_REQUEST_PENDING; |
---|
2152 | 2079 | |
---|
2153 | 2080 | retval = octeon_send_soft_command(oct_dev, sc); |
---|
2154 | 2081 | if (retval == IQ_SEND_FAILED) { |
---|
.. | .. |
---|
2159 | 2086 | /* Sleep on a wait queue till the cond flag indicates that the |
---|
2160 | 2087 | * response arrived or timed-out. |
---|
2161 | 2088 | */ |
---|
2162 | | - if (sleep_cond(&ctx->wc, &ctx->cond) != -EINTR) { |
---|
2163 | | - retval = ctx->status; |
---|
2164 | | - if (retval) |
---|
2165 | | - dev_err(&oct_dev->pci_dev->dev, |
---|
2166 | | - "intrmod config failed. Status: %llx\n", |
---|
2167 | | - CVM_CAST64(retval)); |
---|
2168 | | - else |
---|
2169 | | - dev_info(&oct_dev->pci_dev->dev, |
---|
2170 | | - "Rx-Adaptive Interrupt moderation %s\n", |
---|
2171 | | - (intr_cfg->rx_enable) ? |
---|
2172 | | - "enabled" : "disabled"); |
---|
| 2089 | + retval = wait_for_sc_completion_timeout(oct_dev, sc, 0); |
---|
| 2090 | + if (retval) |
---|
| 2091 | + return retval; |
---|
2173 | 2092 | |
---|
2174 | | - octeon_free_soft_command(oct_dev, sc); |
---|
2175 | | - |
---|
2176 | | - return ((retval) ? -ENODEV : 0); |
---|
| 2093 | + retval = sc->sc_status; |
---|
| 2094 | + if (retval == 0) { |
---|
| 2095 | + dev_info(&oct_dev->pci_dev->dev, |
---|
| 2096 | + "Rx-Adaptive Interrupt moderation %s\n", |
---|
| 2097 | + (intr_cfg->rx_enable) ? |
---|
| 2098 | + "enabled" : "disabled"); |
---|
| 2099 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 2100 | + return 0; |
---|
2177 | 2101 | } |
---|
2178 | 2102 | |
---|
2179 | | - dev_err(&oct_dev->pci_dev->dev, "iq/oq config failed\n"); |
---|
2180 | | - |
---|
2181 | | - return -EINTR; |
---|
| 2103 | + dev_err(&oct_dev->pci_dev->dev, |
---|
| 2104 | + "intrmod config failed. Status: %x\n", retval); |
---|
| 2105 | + WRITE_ONCE(sc->caller_is_done, true); |
---|
| 2106 | + return -ENODEV; |
---|
2182 | 2107 | } |
---|
2183 | 2108 | |
---|
2184 | 2109 | static int lio_get_intr_coalesce(struct net_device *netdev, |
---|
.. | .. |
---|
3123 | 3048 | return 0; |
---|
3124 | 3049 | } |
---|
3125 | 3050 | |
---|
| 3051 | +static int lio_get_fecparam(struct net_device *netdev, |
---|
| 3052 | + struct ethtool_fecparam *fec) |
---|
| 3053 | +{ |
---|
| 3054 | + struct lio *lio = GET_LIO(netdev); |
---|
| 3055 | + struct octeon_device *oct = lio->oct_dev; |
---|
| 3056 | + |
---|
| 3057 | + fec->active_fec = ETHTOOL_FEC_NONE; |
---|
| 3058 | + fec->fec = ETHTOOL_FEC_NONE; |
---|
| 3059 | + |
---|
| 3060 | + if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID || |
---|
| 3061 | + oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) { |
---|
| 3062 | + if (oct->no_speed_setting == 1) |
---|
| 3063 | + return 0; |
---|
| 3064 | + |
---|
| 3065 | + liquidio_get_fec(lio); |
---|
| 3066 | + fec->fec = (ETHTOOL_FEC_RS | ETHTOOL_FEC_OFF); |
---|
| 3067 | + if (oct->props[lio->ifidx].fec == 1) |
---|
| 3068 | + fec->active_fec = ETHTOOL_FEC_RS; |
---|
| 3069 | + else |
---|
| 3070 | + fec->active_fec = ETHTOOL_FEC_OFF; |
---|
| 3071 | + } |
---|
| 3072 | + |
---|
| 3073 | + return 0; |
---|
| 3074 | +} |
---|
| 3075 | + |
---|
| 3076 | +static int lio_set_fecparam(struct net_device *netdev, |
---|
| 3077 | + struct ethtool_fecparam *fec) |
---|
| 3078 | +{ |
---|
| 3079 | + struct lio *lio = GET_LIO(netdev); |
---|
| 3080 | + struct octeon_device *oct = lio->oct_dev; |
---|
| 3081 | + |
---|
| 3082 | + if (oct->subsystem_id == OCTEON_CN2350_25GB_SUBSYS_ID || |
---|
| 3083 | + oct->subsystem_id == OCTEON_CN2360_25GB_SUBSYS_ID) { |
---|
| 3084 | + if (oct->no_speed_setting == 1) |
---|
| 3085 | + return -EOPNOTSUPP; |
---|
| 3086 | + |
---|
| 3087 | + if (fec->fec & ETHTOOL_FEC_OFF) |
---|
| 3088 | + liquidio_set_fec(lio, 0); |
---|
| 3089 | + else if (fec->fec & ETHTOOL_FEC_RS) |
---|
| 3090 | + liquidio_set_fec(lio, 1); |
---|
| 3091 | + else |
---|
| 3092 | + return -EOPNOTSUPP; |
---|
| 3093 | + } else { |
---|
| 3094 | + return -EOPNOTSUPP; |
---|
| 3095 | + } |
---|
| 3096 | + |
---|
| 3097 | + return 0; |
---|
| 3098 | +} |
---|
| 3099 | + |
---|
| 3100 | +#define LIO_ETHTOOL_COALESCE (ETHTOOL_COALESCE_RX_USECS | \ |
---|
| 3101 | + ETHTOOL_COALESCE_MAX_FRAMES | \ |
---|
| 3102 | + ETHTOOL_COALESCE_USE_ADAPTIVE | \ |
---|
| 3103 | + ETHTOOL_COALESCE_RX_MAX_FRAMES_LOW | \ |
---|
| 3104 | + ETHTOOL_COALESCE_TX_MAX_FRAMES_LOW | \ |
---|
| 3105 | + ETHTOOL_COALESCE_RX_MAX_FRAMES_HIGH | \ |
---|
| 3106 | + ETHTOOL_COALESCE_TX_MAX_FRAMES_HIGH | \ |
---|
| 3107 | + ETHTOOL_COALESCE_PKT_RATE_RX_USECS) |
---|
| 3108 | + |
---|
3126 | 3109 | static const struct ethtool_ops lio_ethtool_ops = { |
---|
| 3110 | + .supported_coalesce_params = LIO_ETHTOOL_COALESCE, |
---|
3127 | 3111 | .get_link_ksettings = lio_get_link_ksettings, |
---|
3128 | 3112 | .set_link_ksettings = lio_set_link_ksettings, |
---|
| 3113 | + .get_fecparam = lio_get_fecparam, |
---|
| 3114 | + .set_fecparam = lio_set_fecparam, |
---|
3129 | 3115 | .get_link = ethtool_op_get_link, |
---|
3130 | 3116 | .get_drvinfo = lio_get_drvinfo, |
---|
3131 | 3117 | .get_ringparam = lio_ethtool_get_ringparam, |
---|
.. | .. |
---|
3152 | 3138 | }; |
---|
3153 | 3139 | |
---|
3154 | 3140 | static const struct ethtool_ops lio_vf_ethtool_ops = { |
---|
| 3141 | + .supported_coalesce_params = LIO_ETHTOOL_COALESCE, |
---|
3155 | 3142 | .get_link_ksettings = lio_get_link_ksettings, |
---|
3156 | 3143 | .get_link = ethtool_op_get_link, |
---|
3157 | 3144 | .get_drvinfo = lio_get_vf_drvinfo, |
---|