net/ngbe: initialize and validate EEPROM
[dpdk.git] / drivers / net / ngbe / base / ngbe_hw.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2018-2021 Beijing WangXun Technology Co., Ltd.
3  * Copyright(c) 2010-2017 Intel Corporation
4  */
5
6 #include "ngbe_type.h"
7 #include "ngbe_eeprom.h"
8 #include "ngbe_mng.h"
9 #include "ngbe_hw.h"
10
11 /**
12  *  ngbe_set_lan_id_multi_port - Set LAN id for PCIe multiple port devices
13  *  @hw: pointer to the HW structure
14  *
15  *  Determines the LAN function id by reading memory-mapped registers and swaps
16  *  the port value if requested, and set MAC instance for devices.
17  **/
18 void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw)
19 {
20         struct ngbe_bus_info *bus = &hw->bus;
21         u32 reg = 0;
22
23         DEBUGFUNC("ngbe_set_lan_id_multi_port");
24
25         reg = rd32(hw, NGBE_PORTSTAT);
26         bus->lan_id = NGBE_PORTSTAT_ID(reg);
27         bus->func = bus->lan_id;
28 }
29
30 /**
31  *  ngbe_acquire_swfw_sync - Acquire SWFW semaphore
32  *  @hw: pointer to hardware structure
33  *  @mask: Mask to specify which semaphore to acquire
34  *
35  *  Acquires the SWFW semaphore through the MNGSEM register for the specified
36  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
37  **/
38 s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask)
39 {
40         u32 mngsem = 0;
41         u32 swmask = NGBE_MNGSEM_SW(mask);
42         u32 fwmask = NGBE_MNGSEM_FW(mask);
43         u32 timeout = 200;
44         u32 i;
45
46         DEBUGFUNC("ngbe_acquire_swfw_sync");
47
48         for (i = 0; i < timeout; i++) {
49                 /*
50                  * SW NVM semaphore bit is used for access to all
51                  * SW_FW_SYNC bits (not just NVM)
52                  */
53                 if (ngbe_get_eeprom_semaphore(hw))
54                         return NGBE_ERR_SWFW_SYNC;
55
56                 mngsem = rd32(hw, NGBE_MNGSEM);
57                 if (mngsem & (fwmask | swmask)) {
58                         /* Resource is currently in use by FW or SW */
59                         ngbe_release_eeprom_semaphore(hw);
60                         msec_delay(5);
61                 } else {
62                         mngsem |= swmask;
63                         wr32(hw, NGBE_MNGSEM, mngsem);
64                         ngbe_release_eeprom_semaphore(hw);
65                         return 0;
66                 }
67         }
68
69         /* If time expired clear the bits holding the lock and retry */
70         if (mngsem & (fwmask | swmask))
71                 ngbe_release_swfw_sync(hw, mngsem & (fwmask | swmask));
72
73         msec_delay(5);
74         return NGBE_ERR_SWFW_SYNC;
75 }
76
77 /**
78  *  ngbe_release_swfw_sync - Release SWFW semaphore
79  *  @hw: pointer to hardware structure
80  *  @mask: Mask to specify which semaphore to release
81  *
82  *  Releases the SWFW semaphore through the MNGSEM register for the specified
83  *  function (CSR, PHY0, PHY1, EEPROM, Flash)
84  **/
85 void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask)
86 {
87         u32 mngsem;
88         u32 swmask = mask;
89
90         DEBUGFUNC("ngbe_release_swfw_sync");
91
92         ngbe_get_eeprom_semaphore(hw);
93
94         mngsem = rd32(hw, NGBE_MNGSEM);
95         mngsem &= ~swmask;
96         wr32(hw, NGBE_MNGSEM, mngsem);
97
98         ngbe_release_eeprom_semaphore(hw);
99 }
100
101 /**
102  *  ngbe_set_mac_type - Sets MAC type
103  *  @hw: pointer to the HW structure
104  *
105  *  This function sets the mac type of the adapter based on the
106  *  vendor ID and device ID stored in the hw structure.
107  **/
108 s32 ngbe_set_mac_type(struct ngbe_hw *hw)
109 {
110         s32 err = 0;
111
112         DEBUGFUNC("ngbe_set_mac_type");
113
114         if (hw->vendor_id != PCI_VENDOR_ID_WANGXUN) {
115                 DEBUGOUT("Unsupported vendor id: %x", hw->vendor_id);
116                 return NGBE_ERR_DEVICE_NOT_SUPPORTED;
117         }
118
119         switch (hw->sub_device_id) {
120         case NGBE_SUB_DEV_ID_EM_RTL_SGMII:
121         case NGBE_SUB_DEV_ID_EM_MVL_RGMII:
122                 hw->phy.media_type = ngbe_media_type_copper;
123                 hw->mac.type = ngbe_mac_em;
124                 break;
125         case NGBE_SUB_DEV_ID_EM_MVL_SFP:
126         case NGBE_SUB_DEV_ID_EM_YT8521S_SFP:
127                 hw->phy.media_type = ngbe_media_type_fiber;
128                 hw->mac.type = ngbe_mac_em;
129                 break;
130         case NGBE_SUB_DEV_ID_EM_VF:
131                 hw->phy.media_type = ngbe_media_type_virtual;
132                 hw->mac.type = ngbe_mac_em_vf;
133                 break;
134         default:
135                 err = NGBE_ERR_DEVICE_NOT_SUPPORTED;
136                 hw->phy.media_type = ngbe_media_type_unknown;
137                 hw->mac.type = ngbe_mac_unknown;
138                 DEBUGOUT("Unsupported device id: %x", hw->device_id);
139                 break;
140         }
141
142         DEBUGOUT("found mac: %d media: %d, returns: %d\n",
143                   hw->mac.type, hw->phy.media_type, err);
144         return err;
145 }
146
147 void ngbe_map_device_id(struct ngbe_hw *hw)
148 {
149         u16 oem = hw->sub_system_id & NGBE_OEM_MASK;
150         u16 internal = hw->sub_system_id & NGBE_INTERNAL_MASK;
151         hw->is_pf = true;
152
153         /* move subsystem_device_id to device_id */
154         switch (hw->device_id) {
155         case NGBE_DEV_ID_EM_WX1860AL_W_VF:
156         case NGBE_DEV_ID_EM_WX1860A2_VF:
157         case NGBE_DEV_ID_EM_WX1860A2S_VF:
158         case NGBE_DEV_ID_EM_WX1860A4_VF:
159         case NGBE_DEV_ID_EM_WX1860A4S_VF:
160         case NGBE_DEV_ID_EM_WX1860AL2_VF:
161         case NGBE_DEV_ID_EM_WX1860AL2S_VF:
162         case NGBE_DEV_ID_EM_WX1860AL4_VF:
163         case NGBE_DEV_ID_EM_WX1860AL4S_VF:
164         case NGBE_DEV_ID_EM_WX1860NCSI_VF:
165         case NGBE_DEV_ID_EM_WX1860A1_VF:
166         case NGBE_DEV_ID_EM_WX1860A1L_VF:
167                 hw->device_id = NGBE_DEV_ID_EM_VF;
168                 hw->sub_device_id = NGBE_SUB_DEV_ID_EM_VF;
169                 hw->is_pf = false;
170                 break;
171         case NGBE_DEV_ID_EM_WX1860AL_W:
172         case NGBE_DEV_ID_EM_WX1860A2:
173         case NGBE_DEV_ID_EM_WX1860A2S:
174         case NGBE_DEV_ID_EM_WX1860A4:
175         case NGBE_DEV_ID_EM_WX1860A4S:
176         case NGBE_DEV_ID_EM_WX1860AL2:
177         case NGBE_DEV_ID_EM_WX1860AL2S:
178         case NGBE_DEV_ID_EM_WX1860AL4:
179         case NGBE_DEV_ID_EM_WX1860AL4S:
180         case NGBE_DEV_ID_EM_WX1860NCSI:
181         case NGBE_DEV_ID_EM_WX1860A1:
182         case NGBE_DEV_ID_EM_WX1860A1L:
183                 hw->device_id = NGBE_DEV_ID_EM;
184                 if (oem == NGBE_LY_M88E1512_SFP ||
185                                 internal == NGBE_INTERNAL_SFP)
186                         hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_SFP;
187                 else if (hw->sub_system_id == NGBE_SUB_DEV_ID_EM_M88E1512_RJ45)
188                         hw->sub_device_id = NGBE_SUB_DEV_ID_EM_MVL_RGMII;
189                 else if (oem == NGBE_YT8521S_SFP ||
190                                 oem == NGBE_LY_YT8521S_SFP)
191                         hw->sub_device_id = NGBE_SUB_DEV_ID_EM_YT8521S_SFP;
192                 else
193                         hw->sub_device_id = NGBE_SUB_DEV_ID_EM_RTL_SGMII;
194                 break;
195         default:
196                 break;
197         }
198 }
199
200 /**
201  *  ngbe_init_ops_pf - Inits func ptrs and MAC type
202  *  @hw: pointer to hardware structure
203  *
204  *  Initialize the function pointers and assign the MAC type.
205  *  Does not touch the hardware.
206  **/
207 s32 ngbe_init_ops_pf(struct ngbe_hw *hw)
208 {
209         struct ngbe_bus_info *bus = &hw->bus;
210         struct ngbe_mac_info *mac = &hw->mac;
211         struct ngbe_rom_info *rom = &hw->rom;
212
213         DEBUGFUNC("ngbe_init_ops_pf");
214
215         /* BUS */
216         bus->set_lan_id = ngbe_set_lan_id_multi_port;
217
218         /* MAC */
219         mac->acquire_swfw_sync = ngbe_acquire_swfw_sync;
220         mac->release_swfw_sync = ngbe_release_swfw_sync;
221
222         /* EEPROM */
223         rom->init_params = ngbe_init_eeprom_params;
224         rom->validate_checksum = ngbe_validate_eeprom_checksum_em;
225
226         return 0;
227 }
228
229 /**
230  *  ngbe_init_shared_code - Initialize the shared code
231  *  @hw: pointer to hardware structure
232  *
233  *  This will assign function pointers and assign the MAC type and PHY code.
234  *  Does not touch the hardware. This function must be called prior to any
235  *  other function in the shared code. The ngbe_hw structure should be
236  *  memset to 0 prior to calling this function.  The following fields in
237  *  hw structure should be filled in prior to calling this function:
238  *  hw_addr, back, device_id, vendor_id, subsystem_device_id
239  **/
240 s32 ngbe_init_shared_code(struct ngbe_hw *hw)
241 {
242         s32 status = 0;
243
244         DEBUGFUNC("ngbe_init_shared_code");
245
246         /*
247          * Set the mac type
248          */
249         ngbe_set_mac_type(hw);
250
251         ngbe_init_ops_dummy(hw);
252         switch (hw->mac.type) {
253         case ngbe_mac_em:
254                 ngbe_init_ops_pf(hw);
255                 break;
256         default:
257                 status = NGBE_ERR_DEVICE_NOT_SUPPORTED;
258                 break;
259         }
260
261         hw->bus.set_lan_id(hw);
262
263         return status;
264 }
265