Linux-libre 3.10.48-gnu
[librecmc/linux-libre.git] / drivers / net / ethernet / qlogic / qlcnic / qlcnic_83xx_vnic.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.h"
9 #include "qlcnic_hw.h"
10
11 int qlcnic_83xx_enable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
12 {
13         if (lock) {
14                 if (qlcnic_83xx_lock_driver(adapter))
15                         return -EBUSY;
16         }
17         QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_OPER);
18         if (lock)
19                 qlcnic_83xx_unlock_driver(adapter);
20
21         return 0;
22 }
23
24 int qlcnic_83xx_disable_vnic_mode(struct qlcnic_adapter *adapter, int lock)
25 {
26         struct qlcnic_hardware_context *ahw = adapter->ahw;
27
28         if (lock) {
29                 if (qlcnic_83xx_lock_driver(adapter))
30                         return -EBUSY;
31         }
32
33         QLCWRX(adapter->ahw, QLC_83XX_VNIC_STATE, QLCNIC_DEV_NPAR_NON_OPER);
34         ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
35
36         if (lock)
37                 qlcnic_83xx_unlock_driver(adapter);
38
39         return 0;
40 }
41
42 static int qlcnic_83xx_set_vnic_opmode(struct qlcnic_adapter *adapter)
43 {
44         u8 id;
45         int i, ret = -EBUSY;
46         u32 data = QLCNIC_MGMT_FUNC;
47         struct qlcnic_hardware_context *ahw = adapter->ahw;
48
49         if (qlcnic_83xx_lock_driver(adapter))
50                 return ret;
51
52         if (qlcnic_config_npars) {
53                 for (i = 0; i < ahw->act_pci_func; i++) {
54                         id = adapter->npars[i].pci_func;
55                         if (id == ahw->pci_func)
56                                 continue;
57                         data |= qlcnic_config_npars &
58                                 QLC_83XX_SET_FUNC_OPMODE(0x3, id);
59                 }
60         } else {
61                 data = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
62                 data = (data & ~QLC_83XX_SET_FUNC_OPMODE(0x3, ahw->pci_func)) |
63                        QLC_83XX_SET_FUNC_OPMODE(QLCNIC_MGMT_FUNC,
64                                                 ahw->pci_func);
65         }
66         QLCWRX(adapter->ahw, QLC_83XX_DRV_OP_MODE, data);
67
68         qlcnic_83xx_unlock_driver(adapter);
69
70         return 0;
71 }
72
73 static void
74 qlcnic_83xx_config_vnic_buff_descriptors(struct qlcnic_adapter *adapter)
75 {
76         struct qlcnic_hardware_context *ahw = adapter->ahw;
77
78         if (ahw->port_type == QLCNIC_XGBE) {
79                 adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_VF;
80                 adapter->max_rxd = MAX_RCV_DESCRIPTORS_VF;
81                 adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
82                 adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
83
84         } else if (ahw->port_type == QLCNIC_GBE) {
85                 adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_1G;
86                 adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
87                 adapter->max_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_1G;
88                 adapter->max_rxd = MAX_RCV_DESCRIPTORS_1G;
89         }
90         adapter->num_txd = MAX_CMD_DESCRIPTORS;
91         adapter->max_rds_rings = MAX_RDS_RINGS;
92 }
93
94
95 /**
96  * qlcnic_83xx_init_mgmt_vnic
97  *
98  * @adapter: adapter structure
99  * Management virtual NIC sets the operational mode of other vNIC's and
100  * configures embedded switch (ESWITCH).
101  * Returns: Success(0) or error code.
102  *
103  **/
104 static int qlcnic_83xx_init_mgmt_vnic(struct qlcnic_adapter *adapter)
105 {
106         int err = -EIO;
107
108         qlcnic_83xx_get_minidump_template(adapter);
109         if (!(adapter->flags & QLCNIC_ADAPTER_INITIALIZED)) {
110                 if (qlcnic_init_pci_info(adapter))
111                         return err;
112
113                 if (qlcnic_83xx_set_vnic_opmode(adapter))
114                         return err;
115
116                 if (qlcnic_set_default_offload_settings(adapter))
117                         return err;
118         } else {
119                 if (qlcnic_reset_npar_config(adapter))
120                         return err;
121         }
122
123         if (qlcnic_83xx_get_port_info(adapter))
124                 return err;
125
126         qlcnic_83xx_config_vnic_buff_descriptors(adapter);
127         adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
128         adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
129         qlcnic_83xx_enable_vnic_mode(adapter, 1);
130
131         dev_info(&adapter->pdev->dev, "HAL Version: %d, Management function\n",
132                  adapter->ahw->fw_hal_version);
133
134         return 0;
135 }
136
137 static int qlcnic_83xx_init_privileged_vnic(struct qlcnic_adapter *adapter)
138 {
139         int err = -EIO;
140
141         qlcnic_83xx_get_minidump_template(adapter);
142         if (qlcnic_83xx_get_port_info(adapter))
143                 return err;
144
145         qlcnic_83xx_config_vnic_buff_descriptors(adapter);
146         adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
147         adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
148
149         dev_info(&adapter->pdev->dev,
150                  "HAL Version: %d, Privileged function\n",
151                  adapter->ahw->fw_hal_version);
152         return 0;
153 }
154
155 static int qlcnic_83xx_init_non_privileged_vnic(struct qlcnic_adapter *adapter)
156 {
157         int err = -EIO;
158
159         qlcnic_83xx_get_fw_version(adapter);
160         if (qlcnic_set_eswitch_port_config(adapter))
161                 return err;
162
163         if (qlcnic_83xx_get_port_info(adapter))
164                 return err;
165
166         qlcnic_83xx_config_vnic_buff_descriptors(adapter);
167         adapter->ahw->msix_supported = !!qlcnic_use_msi_x;
168         adapter->flags |= QLCNIC_ADAPTER_INITIALIZED;
169
170         dev_info(&adapter->pdev->dev, "HAL Version: %d, Virtual function\n",
171                  adapter->ahw->fw_hal_version);
172
173         return 0;
174 }
175
176 /**
177  * qlcnic_83xx_vnic_opmode
178  *
179  * @adapter: adapter structure
180  * Identify virtual NIC operational modes.
181  *
182  * Returns: Success(0) or error code.
183  *
184  **/
185 int qlcnic_83xx_config_vnic_opmode(struct qlcnic_adapter *adapter)
186 {
187         u32 op_mode, priv_level;
188         struct qlcnic_hardware_context *ahw = adapter->ahw;
189         struct qlcnic_nic_template *nic_ops = adapter->nic_ops;
190
191         qlcnic_get_func_no(adapter);
192         op_mode = QLCRDX(adapter->ahw, QLC_83XX_DRV_OP_MODE);
193
194         if (op_mode == QLC_83XX_DEFAULT_OPMODE)
195                 priv_level = QLCNIC_MGMT_FUNC;
196         else
197                 priv_level = QLC_83XX_GET_FUNC_PRIVILEGE(op_mode,
198                                                          ahw->pci_func);
199
200         if (priv_level == QLCNIC_NON_PRIV_FUNC) {
201                 ahw->op_mode = QLCNIC_NON_PRIV_FUNC;
202                 ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
203                 nic_ops->init_driver = qlcnic_83xx_init_non_privileged_vnic;
204         } else if (priv_level == QLCNIC_PRIV_FUNC) {
205                 ahw->op_mode = QLCNIC_PRIV_FUNC;
206                 ahw->idc.state_entry = qlcnic_83xx_idc_vnic_pf_entry;
207                 nic_ops->init_driver = qlcnic_83xx_init_privileged_vnic;
208         } else if (priv_level == QLCNIC_MGMT_FUNC) {
209                 ahw->op_mode = QLCNIC_MGMT_FUNC;
210                 ahw->idc.state_entry = qlcnic_83xx_idc_ready_state_entry;
211                 nic_ops->init_driver = qlcnic_83xx_init_mgmt_vnic;
212         } else {
213                 return -EIO;
214         }
215
216         if (ahw->capabilities & BIT_23)
217                 adapter->flags |= QLCNIC_ESWITCH_ENABLED;
218         else
219                 adapter->flags &= ~QLCNIC_ESWITCH_ENABLED;
220
221         adapter->ahw->idc.vnic_state = QLCNIC_DEV_NPAR_NON_OPER;
222         adapter->ahw->idc.vnic_wait_limit = QLCNIC_DEV_NPAR_OPER_TIMEO;
223
224         return 0;
225 }