]>
git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/net/ethernet/netronome/nfp/nfpcore/nfp_nsp_eth.c
2 * Copyright (C) 2015-2017 Netronome Systems, Inc.
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.
9 * The BSD 2-Clause License:
11 * Redistribution and use in source and binary forms, with or
12 * without modification, are permitted provided that the following
15 * 1. Redistributions of source code must retain the above
16 * copyright notice, this list of conditions and the following
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.
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
34 /* Authors: David Brunecz <david.brunecz@netronome.com>
35 * Jakub Kicinski <jakub.kicinski@netronome.com>
36 * Jason Mcmullan <jason.mcmullan@netronome.com>
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>
47 #include "nfp6000/nfp6000.h"
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))
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)
59 #define NSP_ETH_PORT_LANES_MASK cpu_to_le64(NSP_ETH_PORT_LANES)
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_INTERFACE GENMASK_ULL(19, 12)
66 #define NSP_ETH_STATE_MEDIA GENMASK_ULL(21, 20)
67 #define NSP_ETH_STATE_OVRD_CHNG BIT_ULL(22)
68 #define NSP_ETH_STATE_ANEG GENMASK_ULL(25, 23)
70 #define NSP_ETH_CTRL_ENABLED BIT_ULL(1)
71 #define NSP_ETH_CTRL_TX_ENABLED BIT_ULL(2)
72 #define NSP_ETH_CTRL_RX_ENABLED BIT_ULL(3)
83 struct eth_table_entry
{
91 static unsigned int nfp_eth_rate(enum nfp_eth_rate rate
)
93 unsigned int rate_xlate
[] = {
95 [RATE_10M
] = SPEED_10
,
96 [RATE_100M
] = SPEED_100
,
97 [RATE_1G
] = SPEED_1000
,
98 [RATE_10G
] = SPEED_10000
,
99 [RATE_25G
] = SPEED_25000
,
102 if (rate
>= ARRAY_SIZE(rate_xlate
))
105 return rate_xlate
[rate
];
108 static void nfp_eth_copy_mac_reverse(u8
*dst
, const u8
*src
)
112 for (i
= 0; i
< ETH_ALEN
; i
++)
113 dst
[ETH_ALEN
- i
- 1] = src
[i
];
117 nfp_eth_port_translate(struct nfp_nsp
*nsp
, const struct eth_table_entry
*src
,
118 unsigned int index
, struct nfp_eth_table_port
*dst
)
123 port
= le64_to_cpu(src
->port
);
124 state
= le64_to_cpu(src
->state
);
126 dst
->eth_index
= FIELD_GET(NSP_ETH_PORT_INDEX
, port
);
128 dst
->nbi
= index
/ NSP_ETH_NBI_PORT_COUNT
;
129 dst
->base
= index
% NSP_ETH_NBI_PORT_COUNT
;
130 dst
->lanes
= FIELD_GET(NSP_ETH_PORT_LANES
, port
);
132 dst
->enabled
= FIELD_GET(NSP_ETH_STATE_ENABLED
, state
);
133 dst
->tx_enabled
= FIELD_GET(NSP_ETH_STATE_TX_ENABLED
, state
);
134 dst
->rx_enabled
= FIELD_GET(NSP_ETH_STATE_RX_ENABLED
, state
);
136 rate
= nfp_eth_rate(FIELD_GET(NSP_ETH_STATE_RATE
, state
));
137 dst
->speed
= dst
->lanes
* rate
;
139 dst
->interface
= FIELD_GET(NSP_ETH_STATE_INTERFACE
, state
);
140 dst
->media
= FIELD_GET(NSP_ETH_STATE_MEDIA
, state
);
142 nfp_eth_copy_mac_reverse(dst
->mac_addr
, src
->mac_addr
);
144 dst
->label_port
= FIELD_GET(NSP_ETH_PORT_PHYLABEL
, port
);
145 dst
->label_subport
= FIELD_GET(NSP_ETH_PORT_LABEL
, port
);
147 if (nfp_nsp_get_abi_ver_minor(nsp
) < 17)
150 dst
->override_changed
= FIELD_GET(NSP_ETH_STATE_OVRD_CHNG
, state
);
151 dst
->aneg
= FIELD_GET(NSP_ETH_STATE_ANEG
, state
);
155 nfp_eth_mark_split_ports(struct nfp_cpp
*cpp
, struct nfp_eth_table
*table
)
159 for (i
= 0; i
< table
->count
; i
++)
160 for (j
= 0; j
< table
->count
; j
++) {
163 if (table
->ports
[i
].label_port
!=
164 table
->ports
[j
].label_port
)
166 if (table
->ports
[i
].label_subport
==
167 table
->ports
[j
].label_subport
)
169 "Port %d subport %d is a duplicate\n",
170 table
->ports
[i
].label_port
,
171 table
->ports
[i
].label_subport
);
173 table
->ports
[i
].is_split
= true;
179 nfp_eth_calc_port_type(struct nfp_cpp
*cpp
, struct nfp_eth_table_port
*entry
)
181 if (entry
->interface
== NFP_INTERFACE_NONE
) {
182 entry
->port_type
= PORT_NONE
;
186 if (entry
->media
== NFP_MEDIA_FIBRE
)
187 entry
->port_type
= PORT_FIBRE
;
189 entry
->port_type
= PORT_DA
;
193 * nfp_eth_read_ports() - retrieve port information
194 * @cpp: NFP CPP handle
196 * Read the port information from the device. Returned structure should
197 * be freed with kfree() once no longer needed.
199 * Return: populated ETH table or NULL on error.
201 struct nfp_eth_table
*nfp_eth_read_ports(struct nfp_cpp
*cpp
)
203 struct nfp_eth_table
*ret
;
206 nsp
= nfp_nsp_open(cpp
);
210 ret
= __nfp_eth_read_ports(cpp
, nsp
);
216 struct nfp_eth_table
*
217 __nfp_eth_read_ports(struct nfp_cpp
*cpp
, struct nfp_nsp
*nsp
)
219 struct eth_table_entry
*entries
;
220 struct nfp_eth_table
*table
;
221 int i
, j
, ret
, cnt
= 0;
223 entries
= kzalloc(NSP_ETH_TABLE_SIZE
, GFP_KERNEL
);
227 ret
= nfp_nsp_read_eth_table(nsp
, entries
, NSP_ETH_TABLE_SIZE
);
229 nfp_err(cpp
, "reading port table failed %d\n", ret
);
233 for (i
= 0; i
< NSP_ETH_MAX_COUNT
; i
++)
234 if (entries
[i
].port
& NSP_ETH_PORT_LANES_MASK
)
237 /* Some versions of flash will give us 0 instead of port count.
238 * For those that give a port count, verify it against the value
241 if (ret
&& ret
!= cnt
) {
242 nfp_err(cpp
, "table entry count reported (%d) does not match entries present (%d)\n",
247 table
= kzalloc(sizeof(*table
) +
248 sizeof(struct nfp_eth_table_port
) * cnt
, GFP_KERNEL
);
253 for (i
= 0, j
= 0; i
< NSP_ETH_MAX_COUNT
; i
++)
254 if (entries
[i
].port
& NSP_ETH_PORT_LANES_MASK
)
255 nfp_eth_port_translate(nsp
, &entries
[i
], i
,
258 nfp_eth_mark_split_ports(cpp
, table
);
259 for (i
= 0; i
< table
->count
; i
++)
260 nfp_eth_calc_port_type(cpp
, &table
->ports
[i
]);
271 struct nfp_nsp
*nfp_eth_config_start(struct nfp_cpp
*cpp
, unsigned int idx
)
273 struct eth_table_entry
*entries
;
277 entries
= kzalloc(NSP_ETH_TABLE_SIZE
, GFP_KERNEL
);
279 return ERR_PTR(-ENOMEM
);
281 nsp
= nfp_nsp_open(cpp
);
287 ret
= nfp_nsp_read_eth_table(nsp
, entries
, NSP_ETH_TABLE_SIZE
);
289 nfp_err(cpp
, "reading port table failed %d\n", ret
);
293 if (!(entries
[idx
].port
& NSP_ETH_PORT_LANES_MASK
)) {
294 nfp_warn(cpp
, "trying to set port state on disabled port %d\n",
299 nfp_nsp_config_set_state(nsp
, entries
, idx
);
305 return ERR_PTR(-EIO
);
308 void nfp_eth_config_cleanup_end(struct nfp_nsp
*nsp
)
310 struct eth_table_entry
*entries
= nfp_nsp_config_entries(nsp
);
312 nfp_nsp_config_set_modified(nsp
, false);
313 nfp_nsp_config_clear_state(nsp
);
319 * nfp_eth_config_commit_end() - perform recorded configuration changes
320 * @nsp: NFP NSP handle returned from nfp_eth_config_start()
322 * Perform the configuration which was requested with __nfp_eth_set_*()
323 * helpers and recorded in @nsp state. If device was already configured
324 * as requested or no __nfp_eth_set_*() operations were made no NSP command
328 * 0 - configuration successful;
329 * 1 - no changes were needed;
330 * -ERRNO - configuration failed.
332 int nfp_eth_config_commit_end(struct nfp_nsp
*nsp
)
334 struct eth_table_entry
*entries
= nfp_nsp_config_entries(nsp
);
337 if (nfp_nsp_config_modified(nsp
)) {
338 ret
= nfp_nsp_write_eth_table(nsp
, entries
, NSP_ETH_TABLE_SIZE
);
339 ret
= ret
< 0 ? ret
: 0;
342 nfp_eth_config_cleanup_end(nsp
);
348 * nfp_eth_set_mod_enable() - set PHY module enable control bit
349 * @cpp: NFP CPP handle
350 * @idx: NFP chip-wide port index
351 * @enable: Desired state
353 * Enable or disable PHY module (this usually means setting the TX lanes
356 * Return: 0 or -ERRNO.
358 int nfp_eth_set_mod_enable(struct nfp_cpp
*cpp
, unsigned int idx
, bool enable
)
360 struct eth_table_entry
*entries
;
364 nsp
= nfp_eth_config_start(cpp
, idx
);
368 entries
= nfp_nsp_config_entries(nsp
);
370 /* Check if we are already in requested state */
371 reg
= le64_to_cpu(entries
[idx
].state
);
372 if (enable
!= FIELD_GET(NSP_ETH_CTRL_ENABLED
, reg
)) {
373 reg
= le64_to_cpu(entries
[idx
].control
);
374 reg
&= ~NSP_ETH_CTRL_ENABLED
;
375 reg
|= FIELD_PREP(NSP_ETH_CTRL_ENABLED
, enable
);
376 entries
[idx
].control
= cpu_to_le64(reg
);
378 nfp_nsp_config_set_modified(nsp
, true);
381 return nfp_eth_config_commit_end(nsp
);