qlcnic_sriov_common.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  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. #include "qlcnic_sriov.h"
  8. #include "qlcnic.h"
  9. #include "qlcnic_83xx_hw.h"
  10. #include <linux/types.h>
  11. static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {
  12. .read_crb = qlcnic_83xx_read_crb,
  13. .write_crb = qlcnic_83xx_write_crb,
  14. .read_reg = qlcnic_83xx_rd_reg_indirect,
  15. .write_reg = qlcnic_83xx_wrt_reg_indirect,
  16. .get_mac_address = qlcnic_83xx_get_mac_address,
  17. .setup_intr = qlcnic_83xx_setup_intr,
  18. .alloc_mbx_args = qlcnic_83xx_alloc_mbx_args,
  19. .get_func_no = qlcnic_83xx_get_func_no,
  20. .api_lock = qlcnic_83xx_cam_lock,
  21. .api_unlock = qlcnic_83xx_cam_unlock,
  22. .process_lb_rcv_ring_diag = qlcnic_83xx_process_rcv_ring_diag,
  23. .create_rx_ctx = qlcnic_83xx_create_rx_ctx,
  24. .create_tx_ctx = qlcnic_83xx_create_tx_ctx,
  25. .setup_link_event = qlcnic_83xx_setup_link_event,
  26. .get_nic_info = qlcnic_83xx_get_nic_info,
  27. .get_pci_info = qlcnic_83xx_get_pci_info,
  28. .set_nic_info = qlcnic_83xx_set_nic_info,
  29. .change_macvlan = qlcnic_83xx_sre_macaddr_change,
  30. .napi_enable = qlcnic_83xx_napi_enable,
  31. .napi_disable = qlcnic_83xx_napi_disable,
  32. .config_intr_coal = qlcnic_83xx_config_intr_coal,
  33. .config_rss = qlcnic_83xx_config_rss,
  34. .config_hw_lro = qlcnic_83xx_config_hw_lro,
  35. .config_promisc_mode = qlcnic_83xx_nic_set_promisc,
  36. .change_l2_filter = qlcnic_83xx_change_l2_filter,
  37. .get_board_info = qlcnic_83xx_get_port_info,
  38. };
  39. static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {
  40. .config_bridged_mode = qlcnic_config_bridged_mode,
  41. .config_led = qlcnic_config_led,
  42. .cancel_idc_work = qlcnic_83xx_idc_exit,
  43. .napi_add = qlcnic_83xx_napi_add,
  44. .napi_del = qlcnic_83xx_napi_del,
  45. .config_ipaddr = qlcnic_83xx_config_ipaddr,
  46. .clear_legacy_intr = qlcnic_83xx_clear_legacy_intr,
  47. };
  48. int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)
  49. {
  50. struct qlcnic_sriov *sriov;
  51. if (!qlcnic_sriov_enable_check(adapter))
  52. return -EIO;
  53. sriov = kzalloc(sizeof(struct qlcnic_sriov), GFP_KERNEL);
  54. if (!sriov)
  55. return -ENOMEM;
  56. adapter->ahw->sriov = sriov;
  57. sriov->num_vfs = num_vfs;
  58. return 0;
  59. }
  60. void __qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
  61. {
  62. if (!qlcnic_sriov_enable_check(adapter))
  63. return;
  64. kfree(adapter->ahw->sriov);
  65. }
  66. static void qlcnic_sriov_vf_cleanup(struct qlcnic_adapter *adapter)
  67. {
  68. __qlcnic_sriov_cleanup(adapter);
  69. }
  70. void qlcnic_sriov_cleanup(struct qlcnic_adapter *adapter)
  71. {
  72. if (qlcnic_sriov_pf_check(adapter))
  73. qlcnic_sriov_pf_cleanup(adapter);
  74. if (qlcnic_sriov_vf_check(adapter))
  75. qlcnic_sriov_vf_cleanup(adapter);
  76. }
  77. static int qlcnic_sriov_setup_vf(struct qlcnic_adapter *adapter,
  78. int pci_using_dac)
  79. {
  80. int err;
  81. if (!qlcnic_use_msi_x && !!qlcnic_use_msi)
  82. dev_warn(&adapter->pdev->dev,
  83. "83xx adapter do not support MSI interrupts\n");
  84. err = qlcnic_setup_intr(adapter, 1);
  85. if (err) {
  86. dev_err(&adapter->pdev->dev, "Failed to setup interrupt\n");
  87. goto err_out_disable_msi;
  88. }
  89. err = qlcnic_83xx_setup_mbx_intr(adapter);
  90. if (err)
  91. goto err_out_disable_msi;
  92. err = qlcnic_sriov_init(adapter, 1);
  93. if (err)
  94. goto err_out_disable_mbx_intr;
  95. err = qlcnic_setup_netdev(adapter, adapter->netdev, pci_using_dac);
  96. if (err)
  97. goto err_out_cleanup_sriov;
  98. pci_set_drvdata(adapter->pdev, adapter);
  99. dev_info(&adapter->pdev->dev, "%s: XGbE port initialized\n",
  100. adapter->netdev->name);
  101. return 0;
  102. err_out_cleanup_sriov:
  103. __qlcnic_sriov_cleanup(adapter);
  104. err_out_disable_mbx_intr:
  105. qlcnic_83xx_free_mbx_intr(adapter);
  106. err_out_disable_msi:
  107. qlcnic_teardown_intr(adapter);
  108. return err;
  109. }
  110. int qlcnic_sriov_vf_init(struct qlcnic_adapter *adapter, int pci_using_dac)
  111. {
  112. struct qlcnic_hardware_context *ahw = adapter->ahw;
  113. spin_lock_init(&ahw->mbx_lock);
  114. set_bit(QLC_83XX_MBX_READY, &adapter->ahw->idc.status);
  115. ahw->msix_supported = 1;
  116. adapter->flags |= QLCNIC_TX_INTR_SHARED;
  117. if (qlcnic_sriov_setup_vf(adapter, pci_using_dac))
  118. return -EIO;
  119. if (qlcnic_read_mac_addr(adapter))
  120. dev_warn(&adapter->pdev->dev, "failed to read mac addr\n");
  121. set_bit(QLC_83XX_MODULE_LOADED, &adapter->ahw->idc.status);
  122. adapter->ahw->idc.delay = QLC_83XX_IDC_FW_POLL_DELAY;
  123. adapter->ahw->reset_context = 0;
  124. adapter->fw_fail_cnt = 0;
  125. clear_bit(__QLCNIC_RESETTING, &adapter->state);
  126. adapter->need_fw_reset = 0;
  127. return 0;
  128. }
  129. void qlcnic_sriov_vf_set_ops(struct qlcnic_adapter *adapter)
  130. {
  131. struct qlcnic_hardware_context *ahw = adapter->ahw;
  132. ahw->op_mode = QLCNIC_SRIOV_VF_FUNC;
  133. dev_info(&adapter->pdev->dev,
  134. "HAL Version: %d Non Privileged SRIOV function\n",
  135. ahw->fw_hal_version);
  136. adapter->nic_ops = &qlcnic_sriov_vf_ops;
  137. set_bit(__QLCNIC_SRIOV_ENABLE, &adapter->state);
  138. return;
  139. }
  140. void qlcnic_sriov_vf_register_map(struct qlcnic_hardware_context *ahw)
  141. {
  142. ahw->hw_ops = &qlcnic_sriov_vf_hw_ops;
  143. ahw->reg_tbl = (u32 *)qlcnic_83xx_reg_tbl;
  144. ahw->ext_reg_tbl = (u32 *)qlcnic_83xx_ext_reg_tbl;
  145. }