GNU Linux-libre 4.19.304-gnu1
[releases.git] / drivers / staging / rtlwifi / halmac / halmac_88xx / halmac_8822b / halmac_api_8822b_pcie.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  *
4  * Copyright(c) 2016  Realtek Corporation.
5  *
6  * Contact Information:
7  * wlanfae <wlanfae@realtek.com>
8  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
9  * Hsinchu 300, Taiwan.
10  *
11  * Larry Finger <Larry.Finger@lwfinger.net>
12  *
13  *****************************************************************************/
14 #include "../halmac_88xx_cfg.h"
15 #include "../halmac_api_88xx_pcie.h"
16 #include "halmac_8822b_cfg.h"
17
18 /**
19  * halmac_mac_power_switch_8822b_pcie() - switch mac power
20  * @halmac_adapter : the adapter of halmac
21  * @halmac_power : power state
22  * Author : KaiYuan Chang
23  * Return : enum halmac_ret_status
24  * More details of status code can be found in prototype document
25  */
26 enum halmac_ret_status
27 halmac_mac_power_switch_8822b_pcie(struct halmac_adapter *halmac_adapter,
28                                    enum halmac_mac_power halmac_power)
29 {
30         u8 interface_mask;
31         u8 value8;
32         void *driver_adapter = NULL;
33         struct halmac_api *halmac_api;
34
35         if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
36                 return HALMAC_RET_ADAPTER_INVALID;
37
38         if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
39                 return HALMAC_RET_API_INVALID;
40
41         halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_MAC_POWER_SWITCH);
42
43         driver_adapter = halmac_adapter->driver_adapter;
44         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
45
46         HALMAC_RT_TRACE(
47                 driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
48                 "halmac_mac_power_switch_88xx_pcie halmac_power =  %x ==========>\n",
49                 halmac_power);
50         interface_mask = HALMAC_PWR_INTF_PCI_MSK;
51
52         value8 = HALMAC_REG_READ_8(halmac_adapter, REG_CR);
53         if (value8 == 0xEA)
54                 halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_OFF;
55         else
56                 halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_ON;
57
58         /* Check if power switch is needed */
59         if (halmac_power == HALMAC_MAC_POWER_ON &&
60             halmac_adapter->halmac_state.mac_power == HALMAC_MAC_POWER_ON) {
61                 HALMAC_RT_TRACE(
62                         driver_adapter, HALMAC_MSG_PWR, DBG_WARNING,
63                         "halmac_mac_power_switch power state unchange!\n");
64                 return HALMAC_RET_PWR_UNCHANGE;
65         }
66
67         if (halmac_power == HALMAC_MAC_POWER_OFF) {
68                 if (halmac_pwr_seq_parser_88xx(
69                             halmac_adapter, HALMAC_PWR_CUT_ALL_MSK,
70                             HALMAC_PWR_FAB_TSMC_MSK, interface_mask,
71                             halmac_8822b_card_disable_flow) !=
72                     HALMAC_RET_SUCCESS) {
73                         pr_err("Handle power off cmd error\n");
74                         return HALMAC_RET_POWER_OFF_FAIL;
75                 }
76
77                 halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_OFF;
78                 halmac_adapter->halmac_state.ps_state =
79                         HALMAC_PS_STATE_UNDEFINE;
80                 halmac_adapter->halmac_state.dlfw_state = HALMAC_DLFW_NONE;
81                 halmac_init_adapter_dynamic_para_88xx(halmac_adapter);
82         } else {
83                 if (halmac_pwr_seq_parser_88xx(
84                             halmac_adapter, HALMAC_PWR_CUT_ALL_MSK,
85                             HALMAC_PWR_FAB_TSMC_MSK, interface_mask,
86                             halmac_8822b_card_enable_flow) !=
87                     HALMAC_RET_SUCCESS) {
88                         pr_err("Handle power on cmd error\n");
89                         return HALMAC_RET_POWER_ON_FAIL;
90                 }
91
92                 halmac_adapter->halmac_state.mac_power = HALMAC_MAC_POWER_ON;
93                 halmac_adapter->halmac_state.ps_state = HALMAC_PS_STATE_ACT;
94         }
95
96         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
97                         "halmac_mac_power_switch_88xx_pcie <==========\n");
98
99         return HALMAC_RET_SUCCESS;
100 }
101
102 /**
103  * halmac_pcie_switch_8822b() - pcie gen1/gen2 switch
104  * @halmac_adapter : the adapter of halmac
105  * @pcie_cfg : gen1/gen2 selection
106  * Author : KaiYuan Chang
107  * Return : enum halmac_ret_status
108  * More details of status code can be found in prototype document
109  */
110 enum halmac_ret_status
111 halmac_pcie_switch_8822b(struct halmac_adapter *halmac_adapter,
112                          enum halmac_pcie_cfg pcie_cfg)
113 {
114         void *driver_adapter = NULL;
115         struct halmac_api *halmac_api;
116         u8 current_link_speed = 0;
117         u32 count = 0;
118
119         if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
120                 return HALMAC_RET_ADAPTER_INVALID;
121
122         if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
123                 return HALMAC_RET_API_INVALID;
124
125         halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PCIE_SWITCH);
126
127         driver_adapter = halmac_adapter->driver_adapter;
128         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
129
130         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
131                         "%s ==========>\n", __func__);
132
133         /* Link Control 2 Register[3:0] Target Link Speed
134          * Defined encodings are:
135          * 0001b Target Link 2.5 GT/s
136          * 0010b Target Link 5.0 GT/s
137          * 0100b Target Link 8.0 GT/s
138          */
139
140         if (pcie_cfg == HALMAC_PCIE_GEN1) {
141                 /* cfg 0xA0[3:0]=4'b0001 */
142                 halmac_dbi_write8_88xx(
143                         halmac_adapter, LINK_CTRL2_REG_OFFSET,
144                         (halmac_dbi_read8_88xx(halmac_adapter,
145                                                LINK_CTRL2_REG_OFFSET) &
146                          0xF0) | BIT(0));
147
148                 /* cfg 0x80C[17]=1 //PCIe DesignWave */
149                 halmac_dbi_write32_88xx(
150                         halmac_adapter, GEN2_CTRL_OFFSET,
151                         halmac_dbi_read32_88xx(halmac_adapter,
152                                                GEN2_CTRL_OFFSET) |
153                                 BIT(17));
154
155                 /* check link speed if GEN1 */
156                 /* cfg 0x82[3:0]=4'b0001 */
157                 current_link_speed =
158                         halmac_dbi_read8_88xx(halmac_adapter,
159                                               LINK_STATUS_REG_OFFSET) &
160                         0x0F;
161                 count = 2000;
162
163                 while (current_link_speed != GEN1_SPEED && count != 0) {
164                         usleep_range(50, 60);
165                         current_link_speed =
166                                 halmac_dbi_read8_88xx(halmac_adapter,
167                                                       LINK_STATUS_REG_OFFSET) &
168                                 0x0F;
169                         count--;
170                 }
171
172                 if (current_link_speed != GEN1_SPEED) {
173                         pr_err("Speed change to GEN1 fail !\n");
174                         return HALMAC_RET_FAIL;
175                 }
176
177         } else if (pcie_cfg == HALMAC_PCIE_GEN2) {
178                 /* cfg 0xA0[3:0]=4'b0010 */
179                 halmac_dbi_write8_88xx(
180                         halmac_adapter, LINK_CTRL2_REG_OFFSET,
181                         (halmac_dbi_read8_88xx(halmac_adapter,
182                                                LINK_CTRL2_REG_OFFSET) &
183                          0xF0) | BIT(1));
184
185                 /* cfg 0x80C[17]=1 //PCIe DesignWave */
186                 halmac_dbi_write32_88xx(
187                         halmac_adapter, GEN2_CTRL_OFFSET,
188                         halmac_dbi_read32_88xx(halmac_adapter,
189                                                GEN2_CTRL_OFFSET) |
190                                 BIT(17));
191
192                 /* check link speed if GEN2 */
193                 /* cfg 0x82[3:0]=4'b0010 */
194                 current_link_speed =
195                         halmac_dbi_read8_88xx(halmac_adapter,
196                                               LINK_STATUS_REG_OFFSET) &
197                         0x0F;
198                 count = 2000;
199
200                 while (current_link_speed != GEN2_SPEED && count != 0) {
201                         usleep_range(50, 60);
202                         current_link_speed =
203                                 halmac_dbi_read8_88xx(halmac_adapter,
204                                                       LINK_STATUS_REG_OFFSET) &
205                                 0x0F;
206                         count--;
207                 }
208
209                 if (current_link_speed != GEN2_SPEED) {
210                         pr_err("Speed change to GEN1 fail !\n");
211                         return HALMAC_RET_FAIL;
212                 }
213
214         } else {
215                 pr_err("Error Speed !\n");
216                 return HALMAC_RET_FAIL;
217         }
218
219         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
220                         "%s <==========\n", __func__);
221
222         return HALMAC_RET_SUCCESS;
223 }
224
225 enum halmac_ret_status
226 halmac_pcie_switch_8822b_nc(struct halmac_adapter *halmac_adapter,
227                             enum halmac_pcie_cfg pcie_cfg)
228 {
229         void *driver_adapter = NULL;
230         struct halmac_api *halmac_api;
231
232         if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
233                 return HALMAC_RET_ADAPTER_INVALID;
234
235         if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
236                 return HALMAC_RET_API_INVALID;
237
238         halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PCIE_SWITCH);
239
240         driver_adapter = halmac_adapter->driver_adapter;
241         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
242
243         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
244                         "%s ==========>\n", __func__);
245
246         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
247                         "%s <==========\n", __func__);
248
249         return HALMAC_RET_SUCCESS;
250 }
251
252 /**
253  * halmac_phy_cfg_8822b_pcie() - phy config
254  * @halmac_adapter : the adapter of halmac
255  * Author : KaiYuan Chang
256  * Return : enum halmac_ret_status
257  * More details of status code can be found in prototype document
258  */
259 enum halmac_ret_status
260 halmac_phy_cfg_8822b_pcie(struct halmac_adapter *halmac_adapter,
261                           enum halmac_intf_phy_platform platform)
262 {
263         void *driver_adapter = NULL;
264         enum halmac_ret_status status = HALMAC_RET_SUCCESS;
265         struct halmac_api *halmac_api;
266
267         if (halmac_adapter_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
268                 return HALMAC_RET_ADAPTER_INVALID;
269
270         if (halmac_api_validate(halmac_adapter) != HALMAC_RET_SUCCESS)
271                 return HALMAC_RET_API_INVALID;
272
273         halmac_api_record_id_88xx(halmac_adapter, HALMAC_API_PHY_CFG);
274
275         driver_adapter = halmac_adapter->driver_adapter;
276         halmac_api = (struct halmac_api *)halmac_adapter->halmac_api;
277
278         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
279                         "halmac_phy_cfg ==========>\n");
280
281         status = halmac_parse_intf_phy_88xx(halmac_adapter,
282                                             HALMAC_RTL8822B_PCIE_PHY_GEN1,
283                                             platform, HAL_INTF_PHY_PCIE_GEN1);
284
285         if (status != HALMAC_RET_SUCCESS)
286                 return status;
287
288         status = halmac_parse_intf_phy_88xx(halmac_adapter,
289                                             HALMAC_RTL8822B_PCIE_PHY_GEN2,
290                                             platform, HAL_INTF_PHY_PCIE_GEN2);
291
292         if (status != HALMAC_RET_SUCCESS)
293                 return status;
294
295         HALMAC_RT_TRACE(driver_adapter, HALMAC_MSG_PWR, DBG_DMESG,
296                         "halmac_phy_cfg <==========\n");
297
298         return HALMAC_RET_SUCCESS;
299 }
300
301 /**
302  * halmac_interface_integration_tuning_8822b_pcie() - pcie interface fine tuning
303  * @halmac_adapter : the adapter of halmac
304  * Author : Rick Liu
305  * Return : enum halmac_ret_status
306  * More details of status code can be found in prototype document
307  */
308 enum halmac_ret_status halmac_interface_integration_tuning_8822b_pcie(
309         struct halmac_adapter *halmac_adapter)
310 {
311         return HALMAC_RET_SUCCESS;
312 }