]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
nfp: report auto-negotiation in ethtool
[mirror_ubuntu-artful-kernel.git] / drivers / net / ethernet / netronome / nfp / nfpcore / nfp_nsp_eth.c
1 /*
2 * Copyright (C) 2015-2017 Netronome Systems, Inc.
3 *
4 * This software is dual licensed under the GNU General License Version 2,
5 * June 1991 as shown in the file COPYING in the top-level directory of this
6 * source tree or the BSD 2-Clause License provided below. You have the
7 * option to license this software under the complete terms of either license.
8 *
9 * The BSD 2-Clause License:
10 *
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
13 * conditions are met:
14 *
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer.
18 *
19 * 2. Redistributions in binary form must reproduce the above
20 * copyright notice, this list of conditions and the following
21 * disclaimer in the documentation and/or other materials
22 * provided with the distribution.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31 * SOFTWARE.
32 */
33
34 /* Authors: David Brunecz <david.brunecz@netronome.com>
35 * Jakub Kicinski <jakub.kicinski@netronome.com>
36 * Jason Mcmullan <jason.mcmullan@netronome.com>
37 */
38
39 #include <linux/bitfield.h>
40 #include <linux/ethtool.h>
41 #include <linux/if_ether.h>
42 #include <linux/kernel.h>
43 #include <linux/module.h>
44
45 #include "nfp.h"
46 #include "nfp_nsp_eth.h"
47 #include "nfp6000/nfp6000.h"
48
49 #define NSP_ETH_NBI_PORT_COUNT 24
50 #define NSP_ETH_MAX_COUNT (2 * NSP_ETH_NBI_PORT_COUNT)
51 #define NSP_ETH_TABLE_SIZE (NSP_ETH_MAX_COUNT * \
52 sizeof(struct eth_table_entry))
53
54 #define NSP_ETH_PORT_LANES GENMASK_ULL(3, 0)
55 #define NSP_ETH_PORT_INDEX GENMASK_ULL(15, 8)
56 #define NSP_ETH_PORT_LABEL GENMASK_ULL(53, 48)
57 #define NSP_ETH_PORT_PHYLABEL GENMASK_ULL(59, 54)
58
59 #define NSP_ETH_PORT_LANES_MASK cpu_to_le64(NSP_ETH_PORT_LANES)
60
61 #define NSP_ETH_STATE_ENABLED BIT_ULL(1)
62 #define NSP_ETH_STATE_TX_ENABLED BIT_ULL(2)
63 #define NSP_ETH_STATE_RX_ENABLED BIT_ULL(3)
64 #define NSP_ETH_STATE_RATE GENMASK_ULL(11, 8)
65 #define NSP_ETH_STATE_OVRD_CHNG BIT_ULL(22)
66 #define NSP_ETH_STATE_ANEG GENMASK_ULL(25, 23)
67
68 #define NSP_ETH_CTRL_ENABLED BIT_ULL(1)
69 #define NSP_ETH_CTRL_TX_ENABLED BIT_ULL(2)
70 #define NSP_ETH_CTRL_RX_ENABLED BIT_ULL(3)
71
72 enum nfp_eth_rate {
73 RATE_INVALID = 0,
74 RATE_10M,
75 RATE_100M,
76 RATE_1G,
77 RATE_10G,
78 RATE_25G,
79 };
80
81 struct eth_table_entry {
82 __le64 port;
83 __le64 state;
84 u8 mac_addr[6];
85 u8 resv[2];
86 __le64 control;
87 };
88
89 static unsigned int nfp_eth_rate(enum nfp_eth_rate rate)
90 {
91 unsigned int rate_xlate[] = {
92 [RATE_INVALID] = 0,
93 [RATE_10M] = SPEED_10,
94 [RATE_100M] = SPEED_100,
95 [RATE_1G] = SPEED_1000,
96 [RATE_10G] = SPEED_10000,
97 [RATE_25G] = SPEED_25000,
98 };
99
100 if (rate >= ARRAY_SIZE(rate_xlate))
101 return 0;
102
103 return rate_xlate[rate];
104 }
105
106 static void nfp_eth_copy_mac_reverse(u8 *dst, const u8 *src)
107 {
108 int i;
109
110 for (i = 0; i < ETH_ALEN; i++)
111 dst[ETH_ALEN - i - 1] = src[i];
112 }
113
114 static void
115 nfp_eth_port_translate(struct nfp_nsp *nsp, const struct eth_table_entry *src,
116 unsigned int index, struct nfp_eth_table_port *dst)
117 {
118 unsigned int rate;
119 u64 port, state;
120
121 port = le64_to_cpu(src->port);
122 state = le64_to_cpu(src->state);
123
124 dst->eth_index = FIELD_GET(NSP_ETH_PORT_INDEX, port);
125 dst->index = index;
126 dst->nbi = index / NSP_ETH_NBI_PORT_COUNT;
127 dst->base = index % NSP_ETH_NBI_PORT_COUNT;
128 dst->lanes = FIELD_GET(NSP_ETH_PORT_LANES, port);
129
130 dst->enabled = FIELD_GET(NSP_ETH_STATE_ENABLED, state);
131 dst->tx_enabled = FIELD_GET(NSP_ETH_STATE_TX_ENABLED, state);
132 dst->rx_enabled = FIELD_GET(NSP_ETH_STATE_RX_ENABLED, state);
133
134 rate = nfp_eth_rate(FIELD_GET(NSP_ETH_STATE_RATE, state));
135 dst->speed = dst->lanes * rate;
136
137 nfp_eth_copy_mac_reverse(dst->mac_addr, src->mac_addr);
138
139 dst->label_port = FIELD_GET(NSP_ETH_PORT_PHYLABEL, port);
140 dst->label_subport = FIELD_GET(NSP_ETH_PORT_LABEL, port);
141
142 if (nfp_nsp_get_abi_ver_minor(nsp) < 17)
143 return;
144
145 dst->override_changed = FIELD_GET(NSP_ETH_STATE_OVRD_CHNG, state);
146 dst->aneg = FIELD_GET(NSP_ETH_STATE_ANEG, state);
147 }
148
149 static void
150 nfp_eth_mark_split_ports(struct nfp_cpp *cpp, struct nfp_eth_table *table)
151 {
152 unsigned int i, j;
153
154 for (i = 0; i < table->count; i++)
155 for (j = 0; j < table->count; j++) {
156 if (i == j)
157 continue;
158 if (table->ports[i].label_port !=
159 table->ports[j].label_port)
160 continue;
161 if (table->ports[i].label_subport ==
162 table->ports[j].label_subport)
163 nfp_warn(cpp,
164 "Port %d subport %d is a duplicate\n",
165 table->ports[i].label_port,
166 table->ports[i].label_subport);
167
168 table->ports[i].is_split = true;
169 break;
170 }
171 }
172
173 /**
174 * nfp_eth_read_ports() - retrieve port information
175 * @cpp: NFP CPP handle
176 *
177 * Read the port information from the device. Returned structure should
178 * be freed with kfree() once no longer needed.
179 *
180 * Return: populated ETH table or NULL on error.
181 */
182 struct nfp_eth_table *nfp_eth_read_ports(struct nfp_cpp *cpp)
183 {
184 struct nfp_eth_table *ret;
185 struct nfp_nsp *nsp;
186
187 nsp = nfp_nsp_open(cpp);
188 if (IS_ERR(nsp))
189 return NULL;
190
191 ret = __nfp_eth_read_ports(cpp, nsp);
192 nfp_nsp_close(nsp);
193
194 return ret;
195 }
196
197 struct nfp_eth_table *
198 __nfp_eth_read_ports(struct nfp_cpp *cpp, struct nfp_nsp *nsp)
199 {
200 struct eth_table_entry *entries;
201 struct nfp_eth_table *table;
202 int i, j, ret, cnt = 0;
203
204 entries = kzalloc(NSP_ETH_TABLE_SIZE, GFP_KERNEL);
205 if (!entries)
206 return NULL;
207
208 ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
209 if (ret < 0) {
210 nfp_err(cpp, "reading port table failed %d\n", ret);
211 goto err;
212 }
213
214 for (i = 0; i < NSP_ETH_MAX_COUNT; i++)
215 if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
216 cnt++;
217
218 /* Some versions of flash will give us 0 instead of port count.
219 * For those that give a port count, verify it against the value
220 * calculated above.
221 */
222 if (ret && ret != cnt) {
223 nfp_err(cpp, "table entry count reported (%d) does not match entries present (%d)\n",
224 ret, cnt);
225 goto err;
226 }
227
228 table = kzalloc(sizeof(*table) +
229 sizeof(struct nfp_eth_table_port) * cnt, GFP_KERNEL);
230 if (!table)
231 goto err;
232
233 table->count = cnt;
234 for (i = 0, j = 0; i < NSP_ETH_MAX_COUNT; i++)
235 if (entries[i].port & NSP_ETH_PORT_LANES_MASK)
236 nfp_eth_port_translate(nsp, &entries[i], i,
237 &table->ports[j++]);
238
239 nfp_eth_mark_split_ports(cpp, table);
240
241 kfree(entries);
242
243 return table;
244
245 err:
246 kfree(entries);
247 return NULL;
248 }
249
250 /**
251 * nfp_eth_set_mod_enable() - set PHY module enable control bit
252 * @cpp: NFP CPP handle
253 * @idx: NFP chip-wide port index
254 * @enable: Desired state
255 *
256 * Enable or disable PHY module (this usually means setting the TX lanes
257 * disable bits).
258 *
259 * Return: 0 or -ERRNO.
260 */
261 int nfp_eth_set_mod_enable(struct nfp_cpp *cpp, unsigned int idx, bool enable)
262 {
263 struct eth_table_entry *entries;
264 struct nfp_nsp *nsp;
265 u64 reg;
266 int ret;
267
268 entries = kzalloc(NSP_ETH_TABLE_SIZE, GFP_KERNEL);
269 if (!entries)
270 return -ENOMEM;
271
272 nsp = nfp_nsp_open(cpp);
273 if (IS_ERR(nsp)) {
274 kfree(entries);
275 return PTR_ERR(nsp);
276 }
277
278 ret = nfp_nsp_read_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
279 if (ret < 0) {
280 nfp_err(cpp, "reading port table failed %d\n", ret);
281 goto exit_close_nsp;
282 }
283
284 if (!(entries[idx].port & NSP_ETH_PORT_LANES_MASK)) {
285 nfp_warn(cpp, "trying to set port state on disabled port %d\n",
286 idx);
287 ret = -EINVAL;
288 goto exit_close_nsp;
289 }
290
291 /* Check if we are already in requested state */
292 reg = le64_to_cpu(entries[idx].state);
293 if (enable == FIELD_GET(NSP_ETH_CTRL_ENABLED, reg)) {
294 ret = 0;
295 goto exit_close_nsp;
296 }
297
298 reg = le64_to_cpu(entries[idx].control);
299 reg &= ~NSP_ETH_CTRL_ENABLED;
300 reg |= FIELD_PREP(NSP_ETH_CTRL_ENABLED, enable);
301 entries[idx].control = cpu_to_le64(reg);
302
303 ret = nfp_nsp_write_eth_table(nsp, entries, NSP_ETH_TABLE_SIZE);
304 exit_close_nsp:
305 nfp_nsp_close(nsp);
306 kfree(entries);
307
308 return ret < 0 ? ret : 0;
309 }