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