blob: aa330669aa080ed151b798b8cbbddffcfbe49efd [file] [log] [blame]
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001/*
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002 * Keystone GBE and XGBE subsystem code
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05003 *
4 * Copyright (C) 2014 Texas Instruments Incorporated
5 * Authors: Sandeep Nair <sandeep_n@ti.com>
6 * Sandeep Paulraj <s-paulraj@ti.com>
7 * Cyril Chemparathy <cyril@ti.com>
8 * Santosh Shilimkar <santosh.shilimkar@ti.com>
9 * Wingman Kwok <w-kwok2@ti.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation version 2.
14 *
15 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
16 * kind, whether express or implied; without even the implied warranty
17 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20
21#include <linux/io.h>
Karicheri, Muralidharan58c11b52015-01-29 18:15:51 -050022#include <linux/module.h>
Wingman Kwok6f8d3f32015-01-15 19:12:51 -050023#include <linux/of_mdio.h>
24#include <linux/of_address.h>
25#include <linux/if_vlan.h>
26#include <linux/ethtool.h>
27
28#include "cpsw_ale.h"
29#include "netcp.h"
30
31#define NETCP_DRIVER_NAME "TI KeyStone Ethernet Driver"
32#define NETCP_DRIVER_VERSION "v1.0"
33
34#define GBE_IDENT(reg) ((reg >> 16) & 0xffff)
35#define GBE_MAJOR_VERSION(reg) (reg >> 8 & 0x7)
36#define GBE_MINOR_VERSION(reg) (reg & 0xff)
37#define GBE_RTL_VERSION(reg) ((reg >> 11) & 0x1f)
38
39/* 1G Ethernet SS defines */
40#define GBE_MODULE_NAME "netcp-gbe"
41#define GBE_SS_VERSION_14 0x4ed21104
42
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -040043#define GBE_SS_REG_INDEX 0
44#define GBE_SGMII34_REG_INDEX 1
45#define GBE_SM_REG_INDEX 2
46/* offset relative to base of GBE_SS_REG_INDEX */
Wingman Kwok6f8d3f32015-01-15 19:12:51 -050047#define GBE13_SGMII_MODULE_OFFSET 0x100
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -040048/* offset relative to base of GBE_SM_REG_INDEX */
49#define GBE13_HOST_PORT_OFFSET 0x34
50#define GBE13_SLAVE_PORT_OFFSET 0x60
51#define GBE13_EMAC_OFFSET 0x100
52#define GBE13_SLAVE_PORT2_OFFSET 0x200
53#define GBE13_HW_STATS_OFFSET 0x300
54#define GBE13_ALE_OFFSET 0x600
Wingman Kwok6f8d3f32015-01-15 19:12:51 -050055#define GBE13_HOST_PORT_NUM 0
Wingman Kwok6f8d3f32015-01-15 19:12:51 -050056#define GBE13_NUM_ALE_ENTRIES 1024
57
WingMan Kwok9a391c72015-03-20 16:11:25 -040058/* 1G Ethernet NU SS defines */
59#define GBENU_MODULE_NAME "netcp-gbenu"
60#define GBE_SS_ID_NU 0x4ee6
61#define GBE_SS_ID_2U 0x4ee8
62
63#define IS_SS_ID_MU(d) \
64 ((GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU) || \
65 (GBE_IDENT((d)->ss_version) == GBE_SS_ID_2U))
66
67#define IS_SS_ID_NU(d) \
68 (GBE_IDENT((d)->ss_version) == GBE_SS_ID_NU)
69
70#define GBENU_SS_REG_INDEX 0
71#define GBENU_SM_REG_INDEX 1
72#define GBENU_SGMII_MODULE_OFFSET 0x100
73#define GBENU_HOST_PORT_OFFSET 0x1000
74#define GBENU_SLAVE_PORT_OFFSET 0x2000
75#define GBENU_EMAC_OFFSET 0x2330
76#define GBENU_HW_STATS_OFFSET 0x1a000
77#define GBENU_ALE_OFFSET 0x1e000
78#define GBENU_HOST_PORT_NUM 0
79#define GBENU_NUM_ALE_ENTRIES 1024
80
Wingman Kwok90cff9e2015-01-15 19:12:52 -050081/* 10G Ethernet SS defines */
82#define XGBE_MODULE_NAME "netcp-xgbe"
83#define XGBE_SS_VERSION_10 0x4ee42100
84
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -040085#define XGBE_SS_REG_INDEX 0
86#define XGBE_SM_REG_INDEX 1
87#define XGBE_SERDES_REG_INDEX 2
88
89/* offset relative to base of XGBE_SS_REG_INDEX */
Wingman Kwok90cff9e2015-01-15 19:12:52 -050090#define XGBE10_SGMII_MODULE_OFFSET 0x100
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -040091/* offset relative to base of XGBE_SM_REG_INDEX */
92#define XGBE10_HOST_PORT_OFFSET 0x34
93#define XGBE10_SLAVE_PORT_OFFSET 0x64
94#define XGBE10_EMAC_OFFSET 0x400
95#define XGBE10_ALE_OFFSET 0x700
96#define XGBE10_HW_STATS_OFFSET 0x800
Wingman Kwok90cff9e2015-01-15 19:12:52 -050097#define XGBE10_HOST_PORT_NUM 0
Wingman Kwok90cff9e2015-01-15 19:12:52 -050098#define XGBE10_NUM_ALE_ENTRIES 1024
99
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500100#define GBE_TIMER_INTERVAL (HZ / 2)
101
102/* Soft reset register values */
103#define SOFT_RESET_MASK BIT(0)
104#define SOFT_RESET BIT(0)
105#define DEVICE_EMACSL_RESET_POLL_COUNT 100
106#define GMACSL_RET_WARN_RESET_INCOMPLETE -2
107
108#define MACSL_RX_ENABLE_CSF BIT(23)
109#define MACSL_ENABLE_EXT_CTL BIT(18)
Wingman Kwok90cff9e2015-01-15 19:12:52 -0500110#define MACSL_XGMII_ENABLE BIT(13)
111#define MACSL_XGIG_MODE BIT(8)
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500112#define MACSL_GIG_MODE BIT(7)
113#define MACSL_GMII_ENABLE BIT(5)
114#define MACSL_FULLDUPLEX BIT(0)
115
116#define GBE_CTL_P0_ENABLE BIT(2)
WingMan Kwok9a391c72015-03-20 16:11:25 -0400117#define GBE13_REG_VAL_STAT_ENABLE_ALL 0xff
Wingman Kwok90cff9e2015-01-15 19:12:52 -0500118#define XGBE_REG_VAL_STAT_ENABLE_ALL 0xf
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500119#define GBE_STATS_CD_SEL BIT(28)
120
121#define GBE_PORT_MASK(x) (BIT(x) - 1)
122#define GBE_MASK_NO_PORTS 0
123
124#define GBE_DEF_1G_MAC_CONTROL \
125 (MACSL_GIG_MODE | MACSL_GMII_ENABLE | \
126 MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF)
127
Wingman Kwok90cff9e2015-01-15 19:12:52 -0500128#define GBE_DEF_10G_MAC_CONTROL \
129 (MACSL_XGIG_MODE | MACSL_XGMII_ENABLE | \
130 MACSL_ENABLE_EXT_CTL | MACSL_RX_ENABLE_CSF)
131
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500132#define GBE_STATSA_MODULE 0
133#define GBE_STATSB_MODULE 1
134#define GBE_STATSC_MODULE 2
135#define GBE_STATSD_MODULE 3
136
WingMan Kwok9a391c72015-03-20 16:11:25 -0400137#define GBENU_STATS0_MODULE 0
138#define GBENU_STATS1_MODULE 1
139#define GBENU_STATS2_MODULE 2
140#define GBENU_STATS3_MODULE 3
141#define GBENU_STATS4_MODULE 4
142#define GBENU_STATS5_MODULE 5
143#define GBENU_STATS6_MODULE 6
144#define GBENU_STATS7_MODULE 7
145#define GBENU_STATS8_MODULE 8
146
Wingman Kwok90cff9e2015-01-15 19:12:52 -0500147#define XGBE_STATS0_MODULE 0
148#define XGBE_STATS1_MODULE 1
149#define XGBE_STATS2_MODULE 2
150
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500151/* s: 0-based slave_port */
152#define SGMII_BASE(s) \
153 (((s) < 2) ? gbe_dev->sgmii_port_regs : gbe_dev->sgmii_port34_regs)
154
155#define GBE_TX_QUEUE 648
156#define GBE_TXHOOK_ORDER 0
157#define GBE_DEFAULT_ALE_AGEOUT 30
Wingman Kwok90cff9e2015-01-15 19:12:52 -0500158#define SLAVE_LINK_IS_XGMII(s) ((s)->link_interface >= XGMII_LINK_MAC_PHY)
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500159#define NETCP_LINK_STATE_INVALID -1
160
161#define GBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \
162 offsetof(struct gbe##_##rb, rn)
WingMan Kwok9a391c72015-03-20 16:11:25 -0400163#define GBENU_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \
164 offsetof(struct gbenu##_##rb, rn)
Wingman Kwok90cff9e2015-01-15 19:12:52 -0500165#define XGBE_SET_REG_OFS(p, rb, rn) p->rb##_ofs.rn = \
166 offsetof(struct xgbe##_##rb, rn)
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500167#define GBE_REG_ADDR(p, rb, rn) (p->rb + p->rb##_ofs.rn)
168
WingMan Kwok9a391c72015-03-20 16:11:25 -0400169#define HOST_TX_PRI_MAP_DEFAULT 0x00000000
170
Wingman Kwok90cff9e2015-01-15 19:12:52 -0500171struct xgbe_ss_regs {
172 u32 id_ver;
173 u32 synce_count;
174 u32 synce_mux;
175 u32 control;
176};
177
178struct xgbe_switch_regs {
179 u32 id_ver;
180 u32 control;
181 u32 emcontrol;
182 u32 stat_port_en;
183 u32 ptype;
184 u32 soft_idle;
185 u32 thru_rate;
186 u32 gap_thresh;
187 u32 tx_start_wds;
188 u32 flow_control;
189 u32 cppi_thresh;
190};
191
192struct xgbe_port_regs {
193 u32 blk_cnt;
194 u32 port_vlan;
195 u32 tx_pri_map;
196 u32 sa_lo;
197 u32 sa_hi;
198 u32 ts_ctl;
199 u32 ts_seq_ltype;
200 u32 ts_vlan;
201 u32 ts_ctl_ltype2;
202 u32 ts_ctl2;
203 u32 control;
204};
205
206struct xgbe_host_port_regs {
207 u32 blk_cnt;
208 u32 port_vlan;
209 u32 tx_pri_map;
210 u32 src_id;
211 u32 rx_pri_map;
212 u32 rx_maxlen;
213};
214
215struct xgbe_emac_regs {
216 u32 id_ver;
217 u32 mac_control;
218 u32 mac_status;
219 u32 soft_reset;
220 u32 rx_maxlen;
221 u32 __reserved_0;
222 u32 rx_pause;
223 u32 tx_pause;
224 u32 em_control;
225 u32 __reserved_1;
226 u32 tx_gap;
227 u32 rsvd[4];
228};
229
230struct xgbe_host_hw_stats {
231 u32 rx_good_frames;
232 u32 rx_broadcast_frames;
233 u32 rx_multicast_frames;
234 u32 __rsvd_0[3];
235 u32 rx_oversized_frames;
236 u32 __rsvd_1;
237 u32 rx_undersized_frames;
238 u32 __rsvd_2;
239 u32 overrun_type4;
240 u32 overrun_type5;
241 u32 rx_bytes;
242 u32 tx_good_frames;
243 u32 tx_broadcast_frames;
244 u32 tx_multicast_frames;
245 u32 __rsvd_3[9];
246 u32 tx_bytes;
247 u32 tx_64byte_frames;
248 u32 tx_65_to_127byte_frames;
249 u32 tx_128_to_255byte_frames;
250 u32 tx_256_to_511byte_frames;
251 u32 tx_512_to_1023byte_frames;
252 u32 tx_1024byte_frames;
253 u32 net_bytes;
254 u32 rx_sof_overruns;
255 u32 rx_mof_overruns;
256 u32 rx_dma_overruns;
257};
258
259struct xgbe_hw_stats {
260 u32 rx_good_frames;
261 u32 rx_broadcast_frames;
262 u32 rx_multicast_frames;
263 u32 rx_pause_frames;
264 u32 rx_crc_errors;
265 u32 rx_align_code_errors;
266 u32 rx_oversized_frames;
267 u32 rx_jabber_frames;
268 u32 rx_undersized_frames;
269 u32 rx_fragments;
270 u32 overrun_type4;
271 u32 overrun_type5;
272 u32 rx_bytes;
273 u32 tx_good_frames;
274 u32 tx_broadcast_frames;
275 u32 tx_multicast_frames;
276 u32 tx_pause_frames;
277 u32 tx_deferred_frames;
278 u32 tx_collision_frames;
279 u32 tx_single_coll_frames;
280 u32 tx_mult_coll_frames;
281 u32 tx_excessive_collisions;
282 u32 tx_late_collisions;
283 u32 tx_underrun;
284 u32 tx_carrier_sense_errors;
285 u32 tx_bytes;
286 u32 tx_64byte_frames;
287 u32 tx_65_to_127byte_frames;
288 u32 tx_128_to_255byte_frames;
289 u32 tx_256_to_511byte_frames;
290 u32 tx_512_to_1023byte_frames;
291 u32 tx_1024byte_frames;
292 u32 net_bytes;
293 u32 rx_sof_overruns;
294 u32 rx_mof_overruns;
295 u32 rx_dma_overruns;
296};
297
WingMan Kwok9a391c72015-03-20 16:11:25 -0400298struct gbenu_ss_regs {
299 u32 id_ver;
300 u32 synce_count; /* NU */
301 u32 synce_mux; /* NU */
302 u32 control; /* 2U */
303 u32 __rsvd_0[2]; /* 2U */
304 u32 rgmii_status; /* 2U */
305 u32 ss_status; /* 2U */
306};
307
308struct gbenu_switch_regs {
309 u32 id_ver;
310 u32 control;
311 u32 __rsvd_0[2];
312 u32 emcontrol;
313 u32 stat_port_en;
314 u32 ptype; /* NU */
315 u32 soft_idle;
316 u32 thru_rate; /* NU */
317 u32 gap_thresh; /* NU */
318 u32 tx_start_wds; /* NU */
319 u32 eee_prescale; /* 2U */
320 u32 tx_g_oflow_thresh_set; /* NU */
321 u32 tx_g_oflow_thresh_clr; /* NU */
322 u32 tx_g_buf_thresh_set_l; /* NU */
323 u32 tx_g_buf_thresh_set_h; /* NU */
324 u32 tx_g_buf_thresh_clr_l; /* NU */
325 u32 tx_g_buf_thresh_clr_h; /* NU */
326};
327
328struct gbenu_port_regs {
329 u32 __rsvd_0;
330 u32 control;
331 u32 max_blks; /* 2U */
332 u32 mem_align1;
333 u32 blk_cnt;
334 u32 port_vlan;
335 u32 tx_pri_map; /* NU */
336 u32 pri_ctl; /* 2U */
337 u32 rx_pri_map;
338 u32 rx_maxlen;
339 u32 tx_blks_pri; /* NU */
340 u32 __rsvd_1;
341 u32 idle2lpi; /* 2U */
342 u32 lpi2idle; /* 2U */
343 u32 eee_status; /* 2U */
344 u32 __rsvd_2;
345 u32 __rsvd_3[176]; /* NU: more to add */
346 u32 __rsvd_4[2];
347 u32 sa_lo;
348 u32 sa_hi;
349 u32 ts_ctl;
350 u32 ts_seq_ltype;
351 u32 ts_vlan;
352 u32 ts_ctl_ltype2;
353 u32 ts_ctl2;
354};
355
356struct gbenu_host_port_regs {
357 u32 __rsvd_0;
358 u32 control;
359 u32 flow_id_offset; /* 2U */
360 u32 __rsvd_1;
361 u32 blk_cnt;
362 u32 port_vlan;
363 u32 tx_pri_map; /* NU */
364 u32 pri_ctl;
365 u32 rx_pri_map;
366 u32 rx_maxlen;
367 u32 tx_blks_pri; /* NU */
368 u32 __rsvd_2;
369 u32 idle2lpi; /* 2U */
370 u32 lpi2wake; /* 2U */
371 u32 eee_status; /* 2U */
372 u32 __rsvd_3;
373 u32 __rsvd_4[184]; /* NU */
374 u32 host_blks_pri; /* NU */
375};
376
377struct gbenu_emac_regs {
378 u32 mac_control;
379 u32 mac_status;
380 u32 soft_reset;
381 u32 boff_test;
382 u32 rx_pause;
383 u32 __rsvd_0[11]; /* NU */
384 u32 tx_pause;
385 u32 __rsvd_1[11]; /* NU */
386 u32 em_control;
387 u32 tx_gap;
388};
389
390/* Some hw stat regs are applicable to slave port only.
391 * This is handled by gbenu_et_stats struct. Also some
392 * are for SS version NU and some are for 2U.
393 */
394struct gbenu_hw_stats {
395 u32 rx_good_frames;
396 u32 rx_broadcast_frames;
397 u32 rx_multicast_frames;
398 u32 rx_pause_frames; /* slave */
399 u32 rx_crc_errors;
400 u32 rx_align_code_errors; /* slave */
401 u32 rx_oversized_frames;
402 u32 rx_jabber_frames; /* slave */
403 u32 rx_undersized_frames;
404 u32 rx_fragments; /* slave */
405 u32 ale_drop;
406 u32 ale_overrun_drop;
407 u32 rx_bytes;
408 u32 tx_good_frames;
409 u32 tx_broadcast_frames;
410 u32 tx_multicast_frames;
411 u32 tx_pause_frames; /* slave */
412 u32 tx_deferred_frames; /* slave */
413 u32 tx_collision_frames; /* slave */
414 u32 tx_single_coll_frames; /* slave */
415 u32 tx_mult_coll_frames; /* slave */
416 u32 tx_excessive_collisions; /* slave */
417 u32 tx_late_collisions; /* slave */
418 u32 rx_ipg_error; /* slave 10G only */
419 u32 tx_carrier_sense_errors; /* slave */
420 u32 tx_bytes;
421 u32 tx_64B_frames;
422 u32 tx_65_to_127B_frames;
423 u32 tx_128_to_255B_frames;
424 u32 tx_256_to_511B_frames;
425 u32 tx_512_to_1023B_frames;
426 u32 tx_1024B_frames;
427 u32 net_bytes;
428 u32 rx_bottom_fifo_drop;
429 u32 rx_port_mask_drop;
430 u32 rx_top_fifo_drop;
431 u32 ale_rate_limit_drop;
432 u32 ale_vid_ingress_drop;
433 u32 ale_da_eq_sa_drop;
434 u32 __rsvd_0[3];
435 u32 ale_unknown_ucast;
436 u32 ale_unknown_ucast_bytes;
437 u32 ale_unknown_mcast;
438 u32 ale_unknown_mcast_bytes;
439 u32 ale_unknown_bcast;
440 u32 ale_unknown_bcast_bytes;
441 u32 ale_pol_match;
442 u32 ale_pol_match_red; /* NU */
443 u32 ale_pol_match_yellow; /* NU */
444 u32 __rsvd_1[44];
445 u32 tx_mem_protect_err;
446 /* following NU only */
447 u32 tx_pri0;
448 u32 tx_pri1;
449 u32 tx_pri2;
450 u32 tx_pri3;
451 u32 tx_pri4;
452 u32 tx_pri5;
453 u32 tx_pri6;
454 u32 tx_pri7;
455 u32 tx_pri0_bcnt;
456 u32 tx_pri1_bcnt;
457 u32 tx_pri2_bcnt;
458 u32 tx_pri3_bcnt;
459 u32 tx_pri4_bcnt;
460 u32 tx_pri5_bcnt;
461 u32 tx_pri6_bcnt;
462 u32 tx_pri7_bcnt;
463 u32 tx_pri0_drop;
464 u32 tx_pri1_drop;
465 u32 tx_pri2_drop;
466 u32 tx_pri3_drop;
467 u32 tx_pri4_drop;
468 u32 tx_pri5_drop;
469 u32 tx_pri6_drop;
470 u32 tx_pri7_drop;
471 u32 tx_pri0_drop_bcnt;
472 u32 tx_pri1_drop_bcnt;
473 u32 tx_pri2_drop_bcnt;
474 u32 tx_pri3_drop_bcnt;
475 u32 tx_pri4_drop_bcnt;
476 u32 tx_pri5_drop_bcnt;
477 u32 tx_pri6_drop_bcnt;
478 u32 tx_pri7_drop_bcnt;
479};
480
WingMan Kwok9a391c72015-03-20 16:11:25 -0400481#define GBENU_HW_STATS_REG_MAP_SZ 0x200
482
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500483struct gbe_ss_regs {
484 u32 id_ver;
485 u32 synce_count;
486 u32 synce_mux;
487};
488
489struct gbe_ss_regs_ofs {
490 u16 id_ver;
491 u16 control;
492};
493
494struct gbe_switch_regs {
495 u32 id_ver;
496 u32 control;
497 u32 soft_reset;
498 u32 stat_port_en;
499 u32 ptype;
500 u32 soft_idle;
501 u32 thru_rate;
502 u32 gap_thresh;
503 u32 tx_start_wds;
504 u32 flow_control;
505};
506
507struct gbe_switch_regs_ofs {
508 u16 id_ver;
509 u16 control;
510 u16 soft_reset;
511 u16 emcontrol;
512 u16 stat_port_en;
513 u16 ptype;
514 u16 flow_control;
515};
516
517struct gbe_port_regs {
518 u32 max_blks;
519 u32 blk_cnt;
520 u32 port_vlan;
521 u32 tx_pri_map;
522 u32 sa_lo;
523 u32 sa_hi;
524 u32 ts_ctl;
525 u32 ts_seq_ltype;
526 u32 ts_vlan;
527 u32 ts_ctl_ltype2;
528 u32 ts_ctl2;
529};
530
531struct gbe_port_regs_ofs {
532 u16 port_vlan;
533 u16 tx_pri_map;
534 u16 sa_lo;
535 u16 sa_hi;
536 u16 ts_ctl;
537 u16 ts_seq_ltype;
538 u16 ts_vlan;
539 u16 ts_ctl_ltype2;
540 u16 ts_ctl2;
WingMan Kwok9a391c72015-03-20 16:11:25 -0400541 u16 rx_maxlen; /* 2U, NU */
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500542};
543
544struct gbe_host_port_regs {
545 u32 src_id;
546 u32 port_vlan;
547 u32 rx_pri_map;
548 u32 rx_maxlen;
549};
550
551struct gbe_host_port_regs_ofs {
552 u16 port_vlan;
553 u16 tx_pri_map;
554 u16 rx_maxlen;
555};
556
557struct gbe_emac_regs {
558 u32 id_ver;
559 u32 mac_control;
560 u32 mac_status;
561 u32 soft_reset;
562 u32 rx_maxlen;
563 u32 __reserved_0;
564 u32 rx_pause;
565 u32 tx_pause;
566 u32 __reserved_1;
567 u32 rx_pri_map;
568 u32 rsvd[6];
569};
570
571struct gbe_emac_regs_ofs {
572 u16 mac_control;
573 u16 soft_reset;
574 u16 rx_maxlen;
575};
576
577struct gbe_hw_stats {
578 u32 rx_good_frames;
579 u32 rx_broadcast_frames;
580 u32 rx_multicast_frames;
581 u32 rx_pause_frames;
582 u32 rx_crc_errors;
583 u32 rx_align_code_errors;
584 u32 rx_oversized_frames;
585 u32 rx_jabber_frames;
586 u32 rx_undersized_frames;
587 u32 rx_fragments;
588 u32 __pad_0[2];
589 u32 rx_bytes;
590 u32 tx_good_frames;
591 u32 tx_broadcast_frames;
592 u32 tx_multicast_frames;
593 u32 tx_pause_frames;
594 u32 tx_deferred_frames;
595 u32 tx_collision_frames;
596 u32 tx_single_coll_frames;
597 u32 tx_mult_coll_frames;
598 u32 tx_excessive_collisions;
599 u32 tx_late_collisions;
600 u32 tx_underrun;
601 u32 tx_carrier_sense_errors;
602 u32 tx_bytes;
603 u32 tx_64byte_frames;
604 u32 tx_65_to_127byte_frames;
605 u32 tx_128_to_255byte_frames;
606 u32 tx_256_to_511byte_frames;
607 u32 tx_512_to_1023byte_frames;
608 u32 tx_1024byte_frames;
609 u32 net_bytes;
610 u32 rx_sof_overruns;
611 u32 rx_mof_overruns;
612 u32 rx_dma_overruns;
613};
614
WingMan Kwok9a391c72015-03-20 16:11:25 -0400615#define GBE_MAX_HW_STAT_MODS 9
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500616#define GBE_HW_STATS_REG_MAP_SZ 0x100
617
618struct gbe_slave {
619 void __iomem *port_regs;
620 void __iomem *emac_regs;
621 struct gbe_port_regs_ofs port_regs_ofs;
622 struct gbe_emac_regs_ofs emac_regs_ofs;
623 int slave_num; /* 0 based logical number */
624 int port_num; /* actual port number */
625 atomic_t link_state;
626 bool open;
627 struct phy_device *phy;
628 u32 link_interface;
629 u32 mac_control;
630 u8 phy_port_t;
631 struct device_node *phy_node;
632 struct list_head slave_list;
633};
634
635struct gbe_priv {
636 struct device *dev;
637 struct netcp_device *netcp_device;
638 struct timer_list timer;
639 u32 num_slaves;
640 u32 ale_entries;
641 u32 ale_ports;
642 bool enable_ale;
WingMan Kwok9a391c72015-03-20 16:11:25 -0400643 u8 max_num_slaves;
644 u8 max_num_ports; /* max_num_slaves + 1 */
WingMan Kwok489e8a22015-07-23 15:57:23 -0400645 u8 num_stats_mods;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500646 struct netcp_tx_pipe tx_pipe;
647
648 int host_port;
649 u32 rx_packet_max;
650 u32 ss_version;
WingMan Kwok9a391c72015-03-20 16:11:25 -0400651 u32 stats_en_mask;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500652
653 void __iomem *ss_regs;
654 void __iomem *switch_regs;
655 void __iomem *host_port_regs;
656 void __iomem *ale_reg;
657 void __iomem *sgmii_port_regs;
658 void __iomem *sgmii_port34_regs;
659 void __iomem *xgbe_serdes_regs;
660 void __iomem *hw_stats_regs[GBE_MAX_HW_STAT_MODS];
661
662 struct gbe_ss_regs_ofs ss_regs_ofs;
663 struct gbe_switch_regs_ofs switch_regs_ofs;
664 struct gbe_host_port_regs_ofs host_port_regs_ofs;
665
666 struct cpsw_ale *ale;
667 unsigned int tx_queue_id;
668 const char *dma_chan_name;
669
670 struct list_head gbe_intf_head;
671 struct list_head secondary_slaves;
672 struct net_device *dummy_ndev;
673
674 u64 *hw_stats;
WingMan Kwok489e8a22015-07-23 15:57:23 -0400675 u32 *hw_stats_prev;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500676 const struct netcp_ethtool_stat *et_stats;
677 int num_et_stats;
678 /* Lock for updating the hwstats */
679 spinlock_t hw_stats_lock;
680};
681
682struct gbe_intf {
683 struct net_device *ndev;
684 struct device *dev;
685 struct gbe_priv *gbe_dev;
686 struct netcp_tx_pipe tx_pipe;
687 struct gbe_slave *slave;
688 struct list_head gbe_intf_list;
689 unsigned long active_vlans[BITS_TO_LONGS(VLAN_N_VID)];
690};
691
692static struct netcp_module gbe_module;
Wingman Kwok90cff9e2015-01-15 19:12:52 -0500693static struct netcp_module xgbe_module;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500694
695/* Statistic management */
696struct netcp_ethtool_stat {
697 char desc[ETH_GSTRING_LEN];
698 int type;
699 u32 size;
700 int offset;
701};
702
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -0400703#define GBE_STATSA_INFO(field) \
704{ \
705 "GBE_A:"#field, GBE_STATSA_MODULE, \
706 FIELD_SIZEOF(struct gbe_hw_stats, field), \
707 offsetof(struct gbe_hw_stats, field) \
708}
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500709
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -0400710#define GBE_STATSB_INFO(field) \
711{ \
712 "GBE_B:"#field, GBE_STATSB_MODULE, \
713 FIELD_SIZEOF(struct gbe_hw_stats, field), \
714 offsetof(struct gbe_hw_stats, field) \
715}
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500716
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -0400717#define GBE_STATSC_INFO(field) \
718{ \
719 "GBE_C:"#field, GBE_STATSC_MODULE, \
720 FIELD_SIZEOF(struct gbe_hw_stats, field), \
721 offsetof(struct gbe_hw_stats, field) \
722}
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500723
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -0400724#define GBE_STATSD_INFO(field) \
725{ \
726 "GBE_D:"#field, GBE_STATSD_MODULE, \
727 FIELD_SIZEOF(struct gbe_hw_stats, field), \
728 offsetof(struct gbe_hw_stats, field) \
729}
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500730
731static const struct netcp_ethtool_stat gbe13_et_stats[] = {
732 /* GBE module A */
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -0400733 GBE_STATSA_INFO(rx_good_frames),
734 GBE_STATSA_INFO(rx_broadcast_frames),
735 GBE_STATSA_INFO(rx_multicast_frames),
736 GBE_STATSA_INFO(rx_pause_frames),
737 GBE_STATSA_INFO(rx_crc_errors),
738 GBE_STATSA_INFO(rx_align_code_errors),
739 GBE_STATSA_INFO(rx_oversized_frames),
740 GBE_STATSA_INFO(rx_jabber_frames),
741 GBE_STATSA_INFO(rx_undersized_frames),
742 GBE_STATSA_INFO(rx_fragments),
743 GBE_STATSA_INFO(rx_bytes),
744 GBE_STATSA_INFO(tx_good_frames),
745 GBE_STATSA_INFO(tx_broadcast_frames),
746 GBE_STATSA_INFO(tx_multicast_frames),
747 GBE_STATSA_INFO(tx_pause_frames),
748 GBE_STATSA_INFO(tx_deferred_frames),
749 GBE_STATSA_INFO(tx_collision_frames),
750 GBE_STATSA_INFO(tx_single_coll_frames),
751 GBE_STATSA_INFO(tx_mult_coll_frames),
752 GBE_STATSA_INFO(tx_excessive_collisions),
753 GBE_STATSA_INFO(tx_late_collisions),
754 GBE_STATSA_INFO(tx_underrun),
755 GBE_STATSA_INFO(tx_carrier_sense_errors),
756 GBE_STATSA_INFO(tx_bytes),
757 GBE_STATSA_INFO(tx_64byte_frames),
758 GBE_STATSA_INFO(tx_65_to_127byte_frames),
759 GBE_STATSA_INFO(tx_128_to_255byte_frames),
760 GBE_STATSA_INFO(tx_256_to_511byte_frames),
761 GBE_STATSA_INFO(tx_512_to_1023byte_frames),
762 GBE_STATSA_INFO(tx_1024byte_frames),
763 GBE_STATSA_INFO(net_bytes),
764 GBE_STATSA_INFO(rx_sof_overruns),
765 GBE_STATSA_INFO(rx_mof_overruns),
766 GBE_STATSA_INFO(rx_dma_overruns),
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500767 /* GBE module B */
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -0400768 GBE_STATSB_INFO(rx_good_frames),
769 GBE_STATSB_INFO(rx_broadcast_frames),
770 GBE_STATSB_INFO(rx_multicast_frames),
771 GBE_STATSB_INFO(rx_pause_frames),
772 GBE_STATSB_INFO(rx_crc_errors),
773 GBE_STATSB_INFO(rx_align_code_errors),
774 GBE_STATSB_INFO(rx_oversized_frames),
775 GBE_STATSB_INFO(rx_jabber_frames),
776 GBE_STATSB_INFO(rx_undersized_frames),
777 GBE_STATSB_INFO(rx_fragments),
778 GBE_STATSB_INFO(rx_bytes),
779 GBE_STATSB_INFO(tx_good_frames),
780 GBE_STATSB_INFO(tx_broadcast_frames),
781 GBE_STATSB_INFO(tx_multicast_frames),
782 GBE_STATSB_INFO(tx_pause_frames),
783 GBE_STATSB_INFO(tx_deferred_frames),
784 GBE_STATSB_INFO(tx_collision_frames),
785 GBE_STATSB_INFO(tx_single_coll_frames),
786 GBE_STATSB_INFO(tx_mult_coll_frames),
787 GBE_STATSB_INFO(tx_excessive_collisions),
788 GBE_STATSB_INFO(tx_late_collisions),
789 GBE_STATSB_INFO(tx_underrun),
790 GBE_STATSB_INFO(tx_carrier_sense_errors),
791 GBE_STATSB_INFO(tx_bytes),
792 GBE_STATSB_INFO(tx_64byte_frames),
793 GBE_STATSB_INFO(tx_65_to_127byte_frames),
794 GBE_STATSB_INFO(tx_128_to_255byte_frames),
795 GBE_STATSB_INFO(tx_256_to_511byte_frames),
796 GBE_STATSB_INFO(tx_512_to_1023byte_frames),
797 GBE_STATSB_INFO(tx_1024byte_frames),
798 GBE_STATSB_INFO(net_bytes),
799 GBE_STATSB_INFO(rx_sof_overruns),
800 GBE_STATSB_INFO(rx_mof_overruns),
801 GBE_STATSB_INFO(rx_dma_overruns),
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500802 /* GBE module C */
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -0400803 GBE_STATSC_INFO(rx_good_frames),
804 GBE_STATSC_INFO(rx_broadcast_frames),
805 GBE_STATSC_INFO(rx_multicast_frames),
806 GBE_STATSC_INFO(rx_pause_frames),
807 GBE_STATSC_INFO(rx_crc_errors),
808 GBE_STATSC_INFO(rx_align_code_errors),
809 GBE_STATSC_INFO(rx_oversized_frames),
810 GBE_STATSC_INFO(rx_jabber_frames),
811 GBE_STATSC_INFO(rx_undersized_frames),
812 GBE_STATSC_INFO(rx_fragments),
813 GBE_STATSC_INFO(rx_bytes),
814 GBE_STATSC_INFO(tx_good_frames),
815 GBE_STATSC_INFO(tx_broadcast_frames),
816 GBE_STATSC_INFO(tx_multicast_frames),
817 GBE_STATSC_INFO(tx_pause_frames),
818 GBE_STATSC_INFO(tx_deferred_frames),
819 GBE_STATSC_INFO(tx_collision_frames),
820 GBE_STATSC_INFO(tx_single_coll_frames),
821 GBE_STATSC_INFO(tx_mult_coll_frames),
822 GBE_STATSC_INFO(tx_excessive_collisions),
823 GBE_STATSC_INFO(tx_late_collisions),
824 GBE_STATSC_INFO(tx_underrun),
825 GBE_STATSC_INFO(tx_carrier_sense_errors),
826 GBE_STATSC_INFO(tx_bytes),
827 GBE_STATSC_INFO(tx_64byte_frames),
828 GBE_STATSC_INFO(tx_65_to_127byte_frames),
829 GBE_STATSC_INFO(tx_128_to_255byte_frames),
830 GBE_STATSC_INFO(tx_256_to_511byte_frames),
831 GBE_STATSC_INFO(tx_512_to_1023byte_frames),
832 GBE_STATSC_INFO(tx_1024byte_frames),
833 GBE_STATSC_INFO(net_bytes),
834 GBE_STATSC_INFO(rx_sof_overruns),
835 GBE_STATSC_INFO(rx_mof_overruns),
836 GBE_STATSC_INFO(rx_dma_overruns),
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500837 /* GBE module D */
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -0400838 GBE_STATSD_INFO(rx_good_frames),
839 GBE_STATSD_INFO(rx_broadcast_frames),
840 GBE_STATSD_INFO(rx_multicast_frames),
841 GBE_STATSD_INFO(rx_pause_frames),
842 GBE_STATSD_INFO(rx_crc_errors),
843 GBE_STATSD_INFO(rx_align_code_errors),
844 GBE_STATSD_INFO(rx_oversized_frames),
845 GBE_STATSD_INFO(rx_jabber_frames),
846 GBE_STATSD_INFO(rx_undersized_frames),
847 GBE_STATSD_INFO(rx_fragments),
848 GBE_STATSD_INFO(rx_bytes),
849 GBE_STATSD_INFO(tx_good_frames),
850 GBE_STATSD_INFO(tx_broadcast_frames),
851 GBE_STATSD_INFO(tx_multicast_frames),
852 GBE_STATSD_INFO(tx_pause_frames),
853 GBE_STATSD_INFO(tx_deferred_frames),
854 GBE_STATSD_INFO(tx_collision_frames),
855 GBE_STATSD_INFO(tx_single_coll_frames),
856 GBE_STATSD_INFO(tx_mult_coll_frames),
857 GBE_STATSD_INFO(tx_excessive_collisions),
858 GBE_STATSD_INFO(tx_late_collisions),
859 GBE_STATSD_INFO(tx_underrun),
860 GBE_STATSD_INFO(tx_carrier_sense_errors),
861 GBE_STATSD_INFO(tx_bytes),
862 GBE_STATSD_INFO(tx_64byte_frames),
863 GBE_STATSD_INFO(tx_65_to_127byte_frames),
864 GBE_STATSD_INFO(tx_128_to_255byte_frames),
865 GBE_STATSD_INFO(tx_256_to_511byte_frames),
866 GBE_STATSD_INFO(tx_512_to_1023byte_frames),
867 GBE_STATSD_INFO(tx_1024byte_frames),
868 GBE_STATSD_INFO(net_bytes),
869 GBE_STATSD_INFO(rx_sof_overruns),
870 GBE_STATSD_INFO(rx_mof_overruns),
871 GBE_STATSD_INFO(rx_dma_overruns),
Wingman Kwok6f8d3f32015-01-15 19:12:51 -0500872};
873
WingMan Kwok9a391c72015-03-20 16:11:25 -0400874/* This is the size of entries in GBENU_STATS_HOST */
875#define GBENU_ET_STATS_HOST_SIZE 33
876
877#define GBENU_STATS_HOST(field) \
878{ \
879 "GBE_HOST:"#field, GBENU_STATS0_MODULE, \
880 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
881 offsetof(struct gbenu_hw_stats, field) \
882}
883
884/* This is the size of entries in GBENU_STATS_HOST */
885#define GBENU_ET_STATS_PORT_SIZE 46
886
887#define GBENU_STATS_P1(field) \
888{ \
889 "GBE_P1:"#field, GBENU_STATS1_MODULE, \
890 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
891 offsetof(struct gbenu_hw_stats, field) \
892}
893
894#define GBENU_STATS_P2(field) \
895{ \
896 "GBE_P2:"#field, GBENU_STATS2_MODULE, \
897 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
898 offsetof(struct gbenu_hw_stats, field) \
899}
900
901#define GBENU_STATS_P3(field) \
902{ \
903 "GBE_P3:"#field, GBENU_STATS3_MODULE, \
904 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
905 offsetof(struct gbenu_hw_stats, field) \
906}
907
908#define GBENU_STATS_P4(field) \
909{ \
910 "GBE_P4:"#field, GBENU_STATS4_MODULE, \
911 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
912 offsetof(struct gbenu_hw_stats, field) \
913}
914
915#define GBENU_STATS_P5(field) \
916{ \
917 "GBE_P5:"#field, GBENU_STATS5_MODULE, \
918 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
919 offsetof(struct gbenu_hw_stats, field) \
920}
921
922#define GBENU_STATS_P6(field) \
923{ \
924 "GBE_P6:"#field, GBENU_STATS6_MODULE, \
925 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
926 offsetof(struct gbenu_hw_stats, field) \
927}
928
929#define GBENU_STATS_P7(field) \
930{ \
931 "GBE_P7:"#field, GBENU_STATS7_MODULE, \
932 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
933 offsetof(struct gbenu_hw_stats, field) \
934}
935
936#define GBENU_STATS_P8(field) \
937{ \
938 "GBE_P8:"#field, GBENU_STATS8_MODULE, \
939 FIELD_SIZEOF(struct gbenu_hw_stats, field), \
940 offsetof(struct gbenu_hw_stats, field) \
941}
942
943static const struct netcp_ethtool_stat gbenu_et_stats[] = {
944 /* GBENU Host Module */
945 GBENU_STATS_HOST(rx_good_frames),
946 GBENU_STATS_HOST(rx_broadcast_frames),
947 GBENU_STATS_HOST(rx_multicast_frames),
948 GBENU_STATS_HOST(rx_crc_errors),
949 GBENU_STATS_HOST(rx_oversized_frames),
950 GBENU_STATS_HOST(rx_undersized_frames),
951 GBENU_STATS_HOST(ale_drop),
952 GBENU_STATS_HOST(ale_overrun_drop),
953 GBENU_STATS_HOST(rx_bytes),
954 GBENU_STATS_HOST(tx_good_frames),
955 GBENU_STATS_HOST(tx_broadcast_frames),
956 GBENU_STATS_HOST(tx_multicast_frames),
957 GBENU_STATS_HOST(tx_bytes),
958 GBENU_STATS_HOST(tx_64B_frames),
959 GBENU_STATS_HOST(tx_65_to_127B_frames),
960 GBENU_STATS_HOST(tx_128_to_255B_frames),
961 GBENU_STATS_HOST(tx_256_to_511B_frames),
962 GBENU_STATS_HOST(tx_512_to_1023B_frames),
963 GBENU_STATS_HOST(tx_1024B_frames),
964 GBENU_STATS_HOST(net_bytes),
965 GBENU_STATS_HOST(rx_bottom_fifo_drop),
966 GBENU_STATS_HOST(rx_port_mask_drop),
967 GBENU_STATS_HOST(rx_top_fifo_drop),
968 GBENU_STATS_HOST(ale_rate_limit_drop),
969 GBENU_STATS_HOST(ale_vid_ingress_drop),
970 GBENU_STATS_HOST(ale_da_eq_sa_drop),
971 GBENU_STATS_HOST(ale_unknown_ucast),
972 GBENU_STATS_HOST(ale_unknown_ucast_bytes),
973 GBENU_STATS_HOST(ale_unknown_mcast),
974 GBENU_STATS_HOST(ale_unknown_mcast_bytes),
975 GBENU_STATS_HOST(ale_unknown_bcast),
976 GBENU_STATS_HOST(ale_unknown_bcast_bytes),
977 GBENU_STATS_HOST(tx_mem_protect_err),
978 /* GBENU Module 1 */
979 GBENU_STATS_P1(rx_good_frames),
980 GBENU_STATS_P1(rx_broadcast_frames),
981 GBENU_STATS_P1(rx_multicast_frames),
982 GBENU_STATS_P1(rx_pause_frames),
983 GBENU_STATS_P1(rx_crc_errors),
984 GBENU_STATS_P1(rx_align_code_errors),
985 GBENU_STATS_P1(rx_oversized_frames),
986 GBENU_STATS_P1(rx_jabber_frames),
987 GBENU_STATS_P1(rx_undersized_frames),
988 GBENU_STATS_P1(rx_fragments),
989 GBENU_STATS_P1(ale_drop),
990 GBENU_STATS_P1(ale_overrun_drop),
991 GBENU_STATS_P1(rx_bytes),
992 GBENU_STATS_P1(tx_good_frames),
993 GBENU_STATS_P1(tx_broadcast_frames),
994 GBENU_STATS_P1(tx_multicast_frames),
995 GBENU_STATS_P1(tx_pause_frames),
996 GBENU_STATS_P1(tx_deferred_frames),
997 GBENU_STATS_P1(tx_collision_frames),
998 GBENU_STATS_P1(tx_single_coll_frames),
999 GBENU_STATS_P1(tx_mult_coll_frames),
1000 GBENU_STATS_P1(tx_excessive_collisions),
1001 GBENU_STATS_P1(tx_late_collisions),
1002 GBENU_STATS_P1(rx_ipg_error),
1003 GBENU_STATS_P1(tx_carrier_sense_errors),
1004 GBENU_STATS_P1(tx_bytes),
1005 GBENU_STATS_P1(tx_64B_frames),
1006 GBENU_STATS_P1(tx_65_to_127B_frames),
1007 GBENU_STATS_P1(tx_128_to_255B_frames),
1008 GBENU_STATS_P1(tx_256_to_511B_frames),
1009 GBENU_STATS_P1(tx_512_to_1023B_frames),
1010 GBENU_STATS_P1(tx_1024B_frames),
1011 GBENU_STATS_P1(net_bytes),
1012 GBENU_STATS_P1(rx_bottom_fifo_drop),
1013 GBENU_STATS_P1(rx_port_mask_drop),
1014 GBENU_STATS_P1(rx_top_fifo_drop),
1015 GBENU_STATS_P1(ale_rate_limit_drop),
1016 GBENU_STATS_P1(ale_vid_ingress_drop),
1017 GBENU_STATS_P1(ale_da_eq_sa_drop),
1018 GBENU_STATS_P1(ale_unknown_ucast),
1019 GBENU_STATS_P1(ale_unknown_ucast_bytes),
1020 GBENU_STATS_P1(ale_unknown_mcast),
1021 GBENU_STATS_P1(ale_unknown_mcast_bytes),
1022 GBENU_STATS_P1(ale_unknown_bcast),
1023 GBENU_STATS_P1(ale_unknown_bcast_bytes),
1024 GBENU_STATS_P1(tx_mem_protect_err),
1025 /* GBENU Module 2 */
1026 GBENU_STATS_P2(rx_good_frames),
1027 GBENU_STATS_P2(rx_broadcast_frames),
1028 GBENU_STATS_P2(rx_multicast_frames),
1029 GBENU_STATS_P2(rx_pause_frames),
1030 GBENU_STATS_P2(rx_crc_errors),
1031 GBENU_STATS_P2(rx_align_code_errors),
1032 GBENU_STATS_P2(rx_oversized_frames),
1033 GBENU_STATS_P2(rx_jabber_frames),
1034 GBENU_STATS_P2(rx_undersized_frames),
1035 GBENU_STATS_P2(rx_fragments),
1036 GBENU_STATS_P2(ale_drop),
1037 GBENU_STATS_P2(ale_overrun_drop),
1038 GBENU_STATS_P2(rx_bytes),
1039 GBENU_STATS_P2(tx_good_frames),
1040 GBENU_STATS_P2(tx_broadcast_frames),
1041 GBENU_STATS_P2(tx_multicast_frames),
1042 GBENU_STATS_P2(tx_pause_frames),
1043 GBENU_STATS_P2(tx_deferred_frames),
1044 GBENU_STATS_P2(tx_collision_frames),
1045 GBENU_STATS_P2(tx_single_coll_frames),
1046 GBENU_STATS_P2(tx_mult_coll_frames),
1047 GBENU_STATS_P2(tx_excessive_collisions),
1048 GBENU_STATS_P2(tx_late_collisions),
1049 GBENU_STATS_P2(rx_ipg_error),
1050 GBENU_STATS_P2(tx_carrier_sense_errors),
1051 GBENU_STATS_P2(tx_bytes),
1052 GBENU_STATS_P2(tx_64B_frames),
1053 GBENU_STATS_P2(tx_65_to_127B_frames),
1054 GBENU_STATS_P2(tx_128_to_255B_frames),
1055 GBENU_STATS_P2(tx_256_to_511B_frames),
1056 GBENU_STATS_P2(tx_512_to_1023B_frames),
1057 GBENU_STATS_P2(tx_1024B_frames),
1058 GBENU_STATS_P2(net_bytes),
1059 GBENU_STATS_P2(rx_bottom_fifo_drop),
1060 GBENU_STATS_P2(rx_port_mask_drop),
1061 GBENU_STATS_P2(rx_top_fifo_drop),
1062 GBENU_STATS_P2(ale_rate_limit_drop),
1063 GBENU_STATS_P2(ale_vid_ingress_drop),
1064 GBENU_STATS_P2(ale_da_eq_sa_drop),
1065 GBENU_STATS_P2(ale_unknown_ucast),
1066 GBENU_STATS_P2(ale_unknown_ucast_bytes),
1067 GBENU_STATS_P2(ale_unknown_mcast),
1068 GBENU_STATS_P2(ale_unknown_mcast_bytes),
1069 GBENU_STATS_P2(ale_unknown_bcast),
1070 GBENU_STATS_P2(ale_unknown_bcast_bytes),
1071 GBENU_STATS_P2(tx_mem_protect_err),
1072 /* GBENU Module 3 */
1073 GBENU_STATS_P3(rx_good_frames),
1074 GBENU_STATS_P3(rx_broadcast_frames),
1075 GBENU_STATS_P3(rx_multicast_frames),
1076 GBENU_STATS_P3(rx_pause_frames),
1077 GBENU_STATS_P3(rx_crc_errors),
1078 GBENU_STATS_P3(rx_align_code_errors),
1079 GBENU_STATS_P3(rx_oversized_frames),
1080 GBENU_STATS_P3(rx_jabber_frames),
1081 GBENU_STATS_P3(rx_undersized_frames),
1082 GBENU_STATS_P3(rx_fragments),
1083 GBENU_STATS_P3(ale_drop),
1084 GBENU_STATS_P3(ale_overrun_drop),
1085 GBENU_STATS_P3(rx_bytes),
1086 GBENU_STATS_P3(tx_good_frames),
1087 GBENU_STATS_P3(tx_broadcast_frames),
1088 GBENU_STATS_P3(tx_multicast_frames),
1089 GBENU_STATS_P3(tx_pause_frames),
1090 GBENU_STATS_P3(tx_deferred_frames),
1091 GBENU_STATS_P3(tx_collision_frames),
1092 GBENU_STATS_P3(tx_single_coll_frames),
1093 GBENU_STATS_P3(tx_mult_coll_frames),
1094 GBENU_STATS_P3(tx_excessive_collisions),
1095 GBENU_STATS_P3(tx_late_collisions),
1096 GBENU_STATS_P3(rx_ipg_error),
1097 GBENU_STATS_P3(tx_carrier_sense_errors),
1098 GBENU_STATS_P3(tx_bytes),
1099 GBENU_STATS_P3(tx_64B_frames),
1100 GBENU_STATS_P3(tx_65_to_127B_frames),
1101 GBENU_STATS_P3(tx_128_to_255B_frames),
1102 GBENU_STATS_P3(tx_256_to_511B_frames),
1103 GBENU_STATS_P3(tx_512_to_1023B_frames),
1104 GBENU_STATS_P3(tx_1024B_frames),
1105 GBENU_STATS_P3(net_bytes),
1106 GBENU_STATS_P3(rx_bottom_fifo_drop),
1107 GBENU_STATS_P3(rx_port_mask_drop),
1108 GBENU_STATS_P3(rx_top_fifo_drop),
1109 GBENU_STATS_P3(ale_rate_limit_drop),
1110 GBENU_STATS_P3(ale_vid_ingress_drop),
1111 GBENU_STATS_P3(ale_da_eq_sa_drop),
1112 GBENU_STATS_P3(ale_unknown_ucast),
1113 GBENU_STATS_P3(ale_unknown_ucast_bytes),
1114 GBENU_STATS_P3(ale_unknown_mcast),
1115 GBENU_STATS_P3(ale_unknown_mcast_bytes),
1116 GBENU_STATS_P3(ale_unknown_bcast),
1117 GBENU_STATS_P3(ale_unknown_bcast_bytes),
1118 GBENU_STATS_P3(tx_mem_protect_err),
1119 /* GBENU Module 4 */
1120 GBENU_STATS_P4(rx_good_frames),
1121 GBENU_STATS_P4(rx_broadcast_frames),
1122 GBENU_STATS_P4(rx_multicast_frames),
1123 GBENU_STATS_P4(rx_pause_frames),
1124 GBENU_STATS_P4(rx_crc_errors),
1125 GBENU_STATS_P4(rx_align_code_errors),
1126 GBENU_STATS_P4(rx_oversized_frames),
1127 GBENU_STATS_P4(rx_jabber_frames),
1128 GBENU_STATS_P4(rx_undersized_frames),
1129 GBENU_STATS_P4(rx_fragments),
1130 GBENU_STATS_P4(ale_drop),
1131 GBENU_STATS_P4(ale_overrun_drop),
1132 GBENU_STATS_P4(rx_bytes),
1133 GBENU_STATS_P4(tx_good_frames),
1134 GBENU_STATS_P4(tx_broadcast_frames),
1135 GBENU_STATS_P4(tx_multicast_frames),
1136 GBENU_STATS_P4(tx_pause_frames),
1137 GBENU_STATS_P4(tx_deferred_frames),
1138 GBENU_STATS_P4(tx_collision_frames),
1139 GBENU_STATS_P4(tx_single_coll_frames),
1140 GBENU_STATS_P4(tx_mult_coll_frames),
1141 GBENU_STATS_P4(tx_excessive_collisions),
1142 GBENU_STATS_P4(tx_late_collisions),
1143 GBENU_STATS_P4(rx_ipg_error),
1144 GBENU_STATS_P4(tx_carrier_sense_errors),
1145 GBENU_STATS_P4(tx_bytes),
1146 GBENU_STATS_P4(tx_64B_frames),
1147 GBENU_STATS_P4(tx_65_to_127B_frames),
1148 GBENU_STATS_P4(tx_128_to_255B_frames),
1149 GBENU_STATS_P4(tx_256_to_511B_frames),
1150 GBENU_STATS_P4(tx_512_to_1023B_frames),
1151 GBENU_STATS_P4(tx_1024B_frames),
1152 GBENU_STATS_P4(net_bytes),
1153 GBENU_STATS_P4(rx_bottom_fifo_drop),
1154 GBENU_STATS_P4(rx_port_mask_drop),
1155 GBENU_STATS_P4(rx_top_fifo_drop),
1156 GBENU_STATS_P4(ale_rate_limit_drop),
1157 GBENU_STATS_P4(ale_vid_ingress_drop),
1158 GBENU_STATS_P4(ale_da_eq_sa_drop),
1159 GBENU_STATS_P4(ale_unknown_ucast),
1160 GBENU_STATS_P4(ale_unknown_ucast_bytes),
1161 GBENU_STATS_P4(ale_unknown_mcast),
1162 GBENU_STATS_P4(ale_unknown_mcast_bytes),
1163 GBENU_STATS_P4(ale_unknown_bcast),
1164 GBENU_STATS_P4(ale_unknown_bcast_bytes),
1165 GBENU_STATS_P4(tx_mem_protect_err),
1166 /* GBENU Module 5 */
1167 GBENU_STATS_P5(rx_good_frames),
1168 GBENU_STATS_P5(rx_broadcast_frames),
1169 GBENU_STATS_P5(rx_multicast_frames),
1170 GBENU_STATS_P5(rx_pause_frames),
1171 GBENU_STATS_P5(rx_crc_errors),
1172 GBENU_STATS_P5(rx_align_code_errors),
1173 GBENU_STATS_P5(rx_oversized_frames),
1174 GBENU_STATS_P5(rx_jabber_frames),
1175 GBENU_STATS_P5(rx_undersized_frames),
1176 GBENU_STATS_P5(rx_fragments),
1177 GBENU_STATS_P5(ale_drop),
1178 GBENU_STATS_P5(ale_overrun_drop),
1179 GBENU_STATS_P5(rx_bytes),
1180 GBENU_STATS_P5(tx_good_frames),
1181 GBENU_STATS_P5(tx_broadcast_frames),
1182 GBENU_STATS_P5(tx_multicast_frames),
1183 GBENU_STATS_P5(tx_pause_frames),
1184 GBENU_STATS_P5(tx_deferred_frames),
1185 GBENU_STATS_P5(tx_collision_frames),
1186 GBENU_STATS_P5(tx_single_coll_frames),
1187 GBENU_STATS_P5(tx_mult_coll_frames),
1188 GBENU_STATS_P5(tx_excessive_collisions),
1189 GBENU_STATS_P5(tx_late_collisions),
1190 GBENU_STATS_P5(rx_ipg_error),
1191 GBENU_STATS_P5(tx_carrier_sense_errors),
1192 GBENU_STATS_P5(tx_bytes),
1193 GBENU_STATS_P5(tx_64B_frames),
1194 GBENU_STATS_P5(tx_65_to_127B_frames),
1195 GBENU_STATS_P5(tx_128_to_255B_frames),
1196 GBENU_STATS_P5(tx_256_to_511B_frames),
1197 GBENU_STATS_P5(tx_512_to_1023B_frames),
1198 GBENU_STATS_P5(tx_1024B_frames),
1199 GBENU_STATS_P5(net_bytes),
1200 GBENU_STATS_P5(rx_bottom_fifo_drop),
1201 GBENU_STATS_P5(rx_port_mask_drop),
1202 GBENU_STATS_P5(rx_top_fifo_drop),
1203 GBENU_STATS_P5(ale_rate_limit_drop),
1204 GBENU_STATS_P5(ale_vid_ingress_drop),
1205 GBENU_STATS_P5(ale_da_eq_sa_drop),
1206 GBENU_STATS_P5(ale_unknown_ucast),
1207 GBENU_STATS_P5(ale_unknown_ucast_bytes),
1208 GBENU_STATS_P5(ale_unknown_mcast),
1209 GBENU_STATS_P5(ale_unknown_mcast_bytes),
1210 GBENU_STATS_P5(ale_unknown_bcast),
1211 GBENU_STATS_P5(ale_unknown_bcast_bytes),
1212 GBENU_STATS_P5(tx_mem_protect_err),
1213 /* GBENU Module 6 */
1214 GBENU_STATS_P6(rx_good_frames),
1215 GBENU_STATS_P6(rx_broadcast_frames),
1216 GBENU_STATS_P6(rx_multicast_frames),
1217 GBENU_STATS_P6(rx_pause_frames),
1218 GBENU_STATS_P6(rx_crc_errors),
1219 GBENU_STATS_P6(rx_align_code_errors),
1220 GBENU_STATS_P6(rx_oversized_frames),
1221 GBENU_STATS_P6(rx_jabber_frames),
1222 GBENU_STATS_P6(rx_undersized_frames),
1223 GBENU_STATS_P6(rx_fragments),
1224 GBENU_STATS_P6(ale_drop),
1225 GBENU_STATS_P6(ale_overrun_drop),
1226 GBENU_STATS_P6(rx_bytes),
1227 GBENU_STATS_P6(tx_good_frames),
1228 GBENU_STATS_P6(tx_broadcast_frames),
1229 GBENU_STATS_P6(tx_multicast_frames),
1230 GBENU_STATS_P6(tx_pause_frames),
1231 GBENU_STATS_P6(tx_deferred_frames),
1232 GBENU_STATS_P6(tx_collision_frames),
1233 GBENU_STATS_P6(tx_single_coll_frames),
1234 GBENU_STATS_P6(tx_mult_coll_frames),
1235 GBENU_STATS_P6(tx_excessive_collisions),
1236 GBENU_STATS_P6(tx_late_collisions),
1237 GBENU_STATS_P6(rx_ipg_error),
1238 GBENU_STATS_P6(tx_carrier_sense_errors),
1239 GBENU_STATS_P6(tx_bytes),
1240 GBENU_STATS_P6(tx_64B_frames),
1241 GBENU_STATS_P6(tx_65_to_127B_frames),
1242 GBENU_STATS_P6(tx_128_to_255B_frames),
1243 GBENU_STATS_P6(tx_256_to_511B_frames),
1244 GBENU_STATS_P6(tx_512_to_1023B_frames),
1245 GBENU_STATS_P6(tx_1024B_frames),
1246 GBENU_STATS_P6(net_bytes),
1247 GBENU_STATS_P6(rx_bottom_fifo_drop),
1248 GBENU_STATS_P6(rx_port_mask_drop),
1249 GBENU_STATS_P6(rx_top_fifo_drop),
1250 GBENU_STATS_P6(ale_rate_limit_drop),
1251 GBENU_STATS_P6(ale_vid_ingress_drop),
1252 GBENU_STATS_P6(ale_da_eq_sa_drop),
1253 GBENU_STATS_P6(ale_unknown_ucast),
1254 GBENU_STATS_P6(ale_unknown_ucast_bytes),
1255 GBENU_STATS_P6(ale_unknown_mcast),
1256 GBENU_STATS_P6(ale_unknown_mcast_bytes),
1257 GBENU_STATS_P6(ale_unknown_bcast),
1258 GBENU_STATS_P6(ale_unknown_bcast_bytes),
1259 GBENU_STATS_P6(tx_mem_protect_err),
1260 /* GBENU Module 7 */
1261 GBENU_STATS_P7(rx_good_frames),
1262 GBENU_STATS_P7(rx_broadcast_frames),
1263 GBENU_STATS_P7(rx_multicast_frames),
1264 GBENU_STATS_P7(rx_pause_frames),
1265 GBENU_STATS_P7(rx_crc_errors),
1266 GBENU_STATS_P7(rx_align_code_errors),
1267 GBENU_STATS_P7(rx_oversized_frames),
1268 GBENU_STATS_P7(rx_jabber_frames),
1269 GBENU_STATS_P7(rx_undersized_frames),
1270 GBENU_STATS_P7(rx_fragments),
1271 GBENU_STATS_P7(ale_drop),
1272 GBENU_STATS_P7(ale_overrun_drop),
1273 GBENU_STATS_P7(rx_bytes),
1274 GBENU_STATS_P7(tx_good_frames),
1275 GBENU_STATS_P7(tx_broadcast_frames),
1276 GBENU_STATS_P7(tx_multicast_frames),
1277 GBENU_STATS_P7(tx_pause_frames),
1278 GBENU_STATS_P7(tx_deferred_frames),
1279 GBENU_STATS_P7(tx_collision_frames),
1280 GBENU_STATS_P7(tx_single_coll_frames),
1281 GBENU_STATS_P7(tx_mult_coll_frames),
1282 GBENU_STATS_P7(tx_excessive_collisions),
1283 GBENU_STATS_P7(tx_late_collisions),
1284 GBENU_STATS_P7(rx_ipg_error),
1285 GBENU_STATS_P7(tx_carrier_sense_errors),
1286 GBENU_STATS_P7(tx_bytes),
1287 GBENU_STATS_P7(tx_64B_frames),
1288 GBENU_STATS_P7(tx_65_to_127B_frames),
1289 GBENU_STATS_P7(tx_128_to_255B_frames),
1290 GBENU_STATS_P7(tx_256_to_511B_frames),
1291 GBENU_STATS_P7(tx_512_to_1023B_frames),
1292 GBENU_STATS_P7(tx_1024B_frames),
1293 GBENU_STATS_P7(net_bytes),
1294 GBENU_STATS_P7(rx_bottom_fifo_drop),
1295 GBENU_STATS_P7(rx_port_mask_drop),
1296 GBENU_STATS_P7(rx_top_fifo_drop),
1297 GBENU_STATS_P7(ale_rate_limit_drop),
1298 GBENU_STATS_P7(ale_vid_ingress_drop),
1299 GBENU_STATS_P7(ale_da_eq_sa_drop),
1300 GBENU_STATS_P7(ale_unknown_ucast),
1301 GBENU_STATS_P7(ale_unknown_ucast_bytes),
1302 GBENU_STATS_P7(ale_unknown_mcast),
1303 GBENU_STATS_P7(ale_unknown_mcast_bytes),
1304 GBENU_STATS_P7(ale_unknown_bcast),
1305 GBENU_STATS_P7(ale_unknown_bcast_bytes),
1306 GBENU_STATS_P7(tx_mem_protect_err),
1307 /* GBENU Module 8 */
1308 GBENU_STATS_P8(rx_good_frames),
1309 GBENU_STATS_P8(rx_broadcast_frames),
1310 GBENU_STATS_P8(rx_multicast_frames),
1311 GBENU_STATS_P8(rx_pause_frames),
1312 GBENU_STATS_P8(rx_crc_errors),
1313 GBENU_STATS_P8(rx_align_code_errors),
1314 GBENU_STATS_P8(rx_oversized_frames),
1315 GBENU_STATS_P8(rx_jabber_frames),
1316 GBENU_STATS_P8(rx_undersized_frames),
1317 GBENU_STATS_P8(rx_fragments),
1318 GBENU_STATS_P8(ale_drop),
1319 GBENU_STATS_P8(ale_overrun_drop),
1320 GBENU_STATS_P8(rx_bytes),
1321 GBENU_STATS_P8(tx_good_frames),
1322 GBENU_STATS_P8(tx_broadcast_frames),
1323 GBENU_STATS_P8(tx_multicast_frames),
1324 GBENU_STATS_P8(tx_pause_frames),
1325 GBENU_STATS_P8(tx_deferred_frames),
1326 GBENU_STATS_P8(tx_collision_frames),
1327 GBENU_STATS_P8(tx_single_coll_frames),
1328 GBENU_STATS_P8(tx_mult_coll_frames),
1329 GBENU_STATS_P8(tx_excessive_collisions),
1330 GBENU_STATS_P8(tx_late_collisions),
1331 GBENU_STATS_P8(rx_ipg_error),
1332 GBENU_STATS_P8(tx_carrier_sense_errors),
1333 GBENU_STATS_P8(tx_bytes),
1334 GBENU_STATS_P8(tx_64B_frames),
1335 GBENU_STATS_P8(tx_65_to_127B_frames),
1336 GBENU_STATS_P8(tx_128_to_255B_frames),
1337 GBENU_STATS_P8(tx_256_to_511B_frames),
1338 GBENU_STATS_P8(tx_512_to_1023B_frames),
1339 GBENU_STATS_P8(tx_1024B_frames),
1340 GBENU_STATS_P8(net_bytes),
1341 GBENU_STATS_P8(rx_bottom_fifo_drop),
1342 GBENU_STATS_P8(rx_port_mask_drop),
1343 GBENU_STATS_P8(rx_top_fifo_drop),
1344 GBENU_STATS_P8(ale_rate_limit_drop),
1345 GBENU_STATS_P8(ale_vid_ingress_drop),
1346 GBENU_STATS_P8(ale_da_eq_sa_drop),
1347 GBENU_STATS_P8(ale_unknown_ucast),
1348 GBENU_STATS_P8(ale_unknown_ucast_bytes),
1349 GBENU_STATS_P8(ale_unknown_mcast),
1350 GBENU_STATS_P8(ale_unknown_mcast_bytes),
1351 GBENU_STATS_P8(ale_unknown_bcast),
1352 GBENU_STATS_P8(ale_unknown_bcast_bytes),
1353 GBENU_STATS_P8(tx_mem_protect_err),
1354};
1355
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -04001356#define XGBE_STATS0_INFO(field) \
1357{ \
1358 "GBE_0:"#field, XGBE_STATS0_MODULE, \
1359 FIELD_SIZEOF(struct xgbe_hw_stats, field), \
1360 offsetof(struct xgbe_hw_stats, field) \
1361}
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001362
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -04001363#define XGBE_STATS1_INFO(field) \
1364{ \
1365 "GBE_1:"#field, XGBE_STATS1_MODULE, \
1366 FIELD_SIZEOF(struct xgbe_hw_stats, field), \
1367 offsetof(struct xgbe_hw_stats, field) \
1368}
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001369
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -04001370#define XGBE_STATS2_INFO(field) \
1371{ \
1372 "GBE_2:"#field, XGBE_STATS2_MODULE, \
1373 FIELD_SIZEOF(struct xgbe_hw_stats, field), \
1374 offsetof(struct xgbe_hw_stats, field) \
1375}
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001376
1377static const struct netcp_ethtool_stat xgbe10_et_stats[] = {
1378 /* GBE module 0 */
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -04001379 XGBE_STATS0_INFO(rx_good_frames),
1380 XGBE_STATS0_INFO(rx_broadcast_frames),
1381 XGBE_STATS0_INFO(rx_multicast_frames),
1382 XGBE_STATS0_INFO(rx_oversized_frames),
1383 XGBE_STATS0_INFO(rx_undersized_frames),
1384 XGBE_STATS0_INFO(overrun_type4),
1385 XGBE_STATS0_INFO(overrun_type5),
1386 XGBE_STATS0_INFO(rx_bytes),
1387 XGBE_STATS0_INFO(tx_good_frames),
1388 XGBE_STATS0_INFO(tx_broadcast_frames),
1389 XGBE_STATS0_INFO(tx_multicast_frames),
1390 XGBE_STATS0_INFO(tx_bytes),
1391 XGBE_STATS0_INFO(tx_64byte_frames),
1392 XGBE_STATS0_INFO(tx_65_to_127byte_frames),
1393 XGBE_STATS0_INFO(tx_128_to_255byte_frames),
1394 XGBE_STATS0_INFO(tx_256_to_511byte_frames),
1395 XGBE_STATS0_INFO(tx_512_to_1023byte_frames),
1396 XGBE_STATS0_INFO(tx_1024byte_frames),
1397 XGBE_STATS0_INFO(net_bytes),
1398 XGBE_STATS0_INFO(rx_sof_overruns),
1399 XGBE_STATS0_INFO(rx_mof_overruns),
1400 XGBE_STATS0_INFO(rx_dma_overruns),
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001401 /* XGBE module 1 */
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -04001402 XGBE_STATS1_INFO(rx_good_frames),
1403 XGBE_STATS1_INFO(rx_broadcast_frames),
1404 XGBE_STATS1_INFO(rx_multicast_frames),
1405 XGBE_STATS1_INFO(rx_pause_frames),
1406 XGBE_STATS1_INFO(rx_crc_errors),
1407 XGBE_STATS1_INFO(rx_align_code_errors),
1408 XGBE_STATS1_INFO(rx_oversized_frames),
1409 XGBE_STATS1_INFO(rx_jabber_frames),
1410 XGBE_STATS1_INFO(rx_undersized_frames),
1411 XGBE_STATS1_INFO(rx_fragments),
1412 XGBE_STATS1_INFO(overrun_type4),
1413 XGBE_STATS1_INFO(overrun_type5),
1414 XGBE_STATS1_INFO(rx_bytes),
1415 XGBE_STATS1_INFO(tx_good_frames),
1416 XGBE_STATS1_INFO(tx_broadcast_frames),
1417 XGBE_STATS1_INFO(tx_multicast_frames),
1418 XGBE_STATS1_INFO(tx_pause_frames),
1419 XGBE_STATS1_INFO(tx_deferred_frames),
1420 XGBE_STATS1_INFO(tx_collision_frames),
1421 XGBE_STATS1_INFO(tx_single_coll_frames),
1422 XGBE_STATS1_INFO(tx_mult_coll_frames),
1423 XGBE_STATS1_INFO(tx_excessive_collisions),
1424 XGBE_STATS1_INFO(tx_late_collisions),
1425 XGBE_STATS1_INFO(tx_underrun),
1426 XGBE_STATS1_INFO(tx_carrier_sense_errors),
1427 XGBE_STATS1_INFO(tx_bytes),
1428 XGBE_STATS1_INFO(tx_64byte_frames),
1429 XGBE_STATS1_INFO(tx_65_to_127byte_frames),
1430 XGBE_STATS1_INFO(tx_128_to_255byte_frames),
1431 XGBE_STATS1_INFO(tx_256_to_511byte_frames),
1432 XGBE_STATS1_INFO(tx_512_to_1023byte_frames),
1433 XGBE_STATS1_INFO(tx_1024byte_frames),
1434 XGBE_STATS1_INFO(net_bytes),
1435 XGBE_STATS1_INFO(rx_sof_overruns),
1436 XGBE_STATS1_INFO(rx_mof_overruns),
1437 XGBE_STATS1_INFO(rx_dma_overruns),
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001438 /* XGBE module 2 */
Karicheri, Muralidharanda866ba2015-03-20 16:11:24 -04001439 XGBE_STATS2_INFO(rx_good_frames),
1440 XGBE_STATS2_INFO(rx_broadcast_frames),
1441 XGBE_STATS2_INFO(rx_multicast_frames),
1442 XGBE_STATS2_INFO(rx_pause_frames),
1443 XGBE_STATS2_INFO(rx_crc_errors),
1444 XGBE_STATS2_INFO(rx_align_code_errors),
1445 XGBE_STATS2_INFO(rx_oversized_frames),
1446 XGBE_STATS2_INFO(rx_jabber_frames),
1447 XGBE_STATS2_INFO(rx_undersized_frames),
1448 XGBE_STATS2_INFO(rx_fragments),
1449 XGBE_STATS2_INFO(overrun_type4),
1450 XGBE_STATS2_INFO(overrun_type5),
1451 XGBE_STATS2_INFO(rx_bytes),
1452 XGBE_STATS2_INFO(tx_good_frames),
1453 XGBE_STATS2_INFO(tx_broadcast_frames),
1454 XGBE_STATS2_INFO(tx_multicast_frames),
1455 XGBE_STATS2_INFO(tx_pause_frames),
1456 XGBE_STATS2_INFO(tx_deferred_frames),
1457 XGBE_STATS2_INFO(tx_collision_frames),
1458 XGBE_STATS2_INFO(tx_single_coll_frames),
1459 XGBE_STATS2_INFO(tx_mult_coll_frames),
1460 XGBE_STATS2_INFO(tx_excessive_collisions),
1461 XGBE_STATS2_INFO(tx_late_collisions),
1462 XGBE_STATS2_INFO(tx_underrun),
1463 XGBE_STATS2_INFO(tx_carrier_sense_errors),
1464 XGBE_STATS2_INFO(tx_bytes),
1465 XGBE_STATS2_INFO(tx_64byte_frames),
1466 XGBE_STATS2_INFO(tx_65_to_127byte_frames),
1467 XGBE_STATS2_INFO(tx_128_to_255byte_frames),
1468 XGBE_STATS2_INFO(tx_256_to_511byte_frames),
1469 XGBE_STATS2_INFO(tx_512_to_1023byte_frames),
1470 XGBE_STATS2_INFO(tx_1024byte_frames),
1471 XGBE_STATS2_INFO(net_bytes),
1472 XGBE_STATS2_INFO(rx_sof_overruns),
1473 XGBE_STATS2_INFO(rx_mof_overruns),
1474 XGBE_STATS2_INFO(rx_dma_overruns),
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001475};
1476
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001477#define for_each_intf(i, priv) \
1478 list_for_each_entry((i), &(priv)->gbe_intf_head, gbe_intf_list)
1479
1480#define for_each_sec_slave(slave, priv) \
1481 list_for_each_entry((slave), &(priv)->secondary_slaves, slave_list)
1482
1483#define first_sec_slave(priv) \
1484 list_first_entry(&priv->secondary_slaves, \
1485 struct gbe_slave, slave_list)
1486
1487static void keystone_get_drvinfo(struct net_device *ndev,
1488 struct ethtool_drvinfo *info)
1489{
1490 strncpy(info->driver, NETCP_DRIVER_NAME, sizeof(info->driver));
1491 strncpy(info->version, NETCP_DRIVER_VERSION, sizeof(info->version));
1492}
1493
1494static u32 keystone_get_msglevel(struct net_device *ndev)
1495{
1496 struct netcp_intf *netcp = netdev_priv(ndev);
1497
1498 return netcp->msg_enable;
1499}
1500
1501static void keystone_set_msglevel(struct net_device *ndev, u32 value)
1502{
1503 struct netcp_intf *netcp = netdev_priv(ndev);
1504
1505 netcp->msg_enable = value;
1506}
1507
1508static void keystone_get_stat_strings(struct net_device *ndev,
1509 uint32_t stringset, uint8_t *data)
1510{
1511 struct netcp_intf *netcp = netdev_priv(ndev);
1512 struct gbe_intf *gbe_intf;
1513 struct gbe_priv *gbe_dev;
1514 int i;
1515
1516 gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
1517 if (!gbe_intf)
1518 return;
1519 gbe_dev = gbe_intf->gbe_dev;
1520
1521 switch (stringset) {
1522 case ETH_SS_STATS:
1523 for (i = 0; i < gbe_dev->num_et_stats; i++) {
1524 memcpy(data, gbe_dev->et_stats[i].desc,
1525 ETH_GSTRING_LEN);
1526 data += ETH_GSTRING_LEN;
1527 }
1528 break;
1529 case ETH_SS_TEST:
1530 break;
1531 }
1532}
1533
1534static int keystone_get_sset_count(struct net_device *ndev, int stringset)
1535{
1536 struct netcp_intf *netcp = netdev_priv(ndev);
1537 struct gbe_intf *gbe_intf;
1538 struct gbe_priv *gbe_dev;
1539
1540 gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
1541 if (!gbe_intf)
1542 return -EINVAL;
1543 gbe_dev = gbe_intf->gbe_dev;
1544
1545 switch (stringset) {
1546 case ETH_SS_TEST:
1547 return 0;
1548 case ETH_SS_STATS:
1549 return gbe_dev->num_et_stats;
1550 default:
1551 return -EINVAL;
1552 }
1553}
1554
WingMan Kwok489e8a22015-07-23 15:57:23 -04001555static void gbe_reset_mod_stats(struct gbe_priv *gbe_dev, int stats_mod)
1556{
1557 void __iomem *base = gbe_dev->hw_stats_regs[stats_mod];
1558 u32 __iomem *p_stats_entry;
1559 int i;
1560
1561 for (i = 0; i < gbe_dev->num_et_stats; i++) {
1562 if (gbe_dev->et_stats[i].type == stats_mod) {
1563 p_stats_entry = base + gbe_dev->et_stats[i].offset;
1564 gbe_dev->hw_stats[i] = 0;
1565 gbe_dev->hw_stats_prev[i] = readl(p_stats_entry);
1566 }
1567 }
1568}
1569
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001570static inline void gbe_update_hw_stats_entry(struct gbe_priv *gbe_dev,
1571 int et_stats_entry)
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001572{
1573 void __iomem *base = NULL;
WingMan Kwok489e8a22015-07-23 15:57:23 -04001574 u32 __iomem *p_stats_entry;
1575 u32 curr, delta;
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001576
1577 /* The hw_stats_regs pointers are already
1578 * properly set to point to the right base:
1579 */
1580 base = gbe_dev->hw_stats_regs[gbe_dev->et_stats[et_stats_entry].type];
WingMan Kwok489e8a22015-07-23 15:57:23 -04001581 p_stats_entry = base + gbe_dev->et_stats[et_stats_entry].offset;
1582 curr = readl(p_stats_entry);
1583 delta = curr - gbe_dev->hw_stats_prev[et_stats_entry];
1584 gbe_dev->hw_stats_prev[et_stats_entry] = curr;
1585 gbe_dev->hw_stats[et_stats_entry] += delta;
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001586}
1587
1588static void gbe_update_stats(struct gbe_priv *gbe_dev, uint64_t *data)
1589{
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001590 int i;
1591
1592 for (i = 0; i < gbe_dev->num_et_stats; i++) {
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001593 gbe_update_hw_stats_entry(gbe_dev, i);
1594
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001595 if (data)
1596 data[i] = gbe_dev->hw_stats[i];
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001597 }
1598}
1599
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001600static inline void gbe_stats_mod_visible_ver14(struct gbe_priv *gbe_dev,
1601 int stats_mod)
1602{
1603 u32 val;
1604
1605 val = readl(GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
1606
1607 switch (stats_mod) {
1608 case GBE_STATSA_MODULE:
1609 case GBE_STATSB_MODULE:
1610 val &= ~GBE_STATS_CD_SEL;
1611 break;
1612 case GBE_STATSC_MODULE:
1613 case GBE_STATSD_MODULE:
1614 val |= GBE_STATS_CD_SEL;
1615 break;
1616 default:
1617 return;
1618 }
1619
1620 /* make the stat module visible */
1621 writel(val, GBE_REG_ADDR(gbe_dev, switch_regs, stat_port_en));
1622}
1623
WingMan Kwok489e8a22015-07-23 15:57:23 -04001624static void gbe_reset_mod_stats_ver14(struct gbe_priv *gbe_dev, int stats_mod)
1625{
1626 gbe_stats_mod_visible_ver14(gbe_dev, stats_mod);
1627 gbe_reset_mod_stats(gbe_dev, stats_mod);
1628}
1629
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001630static void gbe_update_stats_ver14(struct gbe_priv *gbe_dev, uint64_t *data)
1631{
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001632 u32 half_num_et_stats = (gbe_dev->num_et_stats / 2);
1633 int et_entry, j, pair;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001634
1635 for (pair = 0; pair < 2; pair++) {
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001636 gbe_stats_mod_visible_ver14(gbe_dev, (pair ?
1637 GBE_STATSC_MODULE :
1638 GBE_STATSA_MODULE));
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001639
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001640 for (j = 0; j < half_num_et_stats; j++) {
1641 et_entry = pair * half_num_et_stats + j;
1642 gbe_update_hw_stats_entry(gbe_dev, et_entry);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001643
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001644 if (data)
WingMan Kwokfbf64c12015-07-23 15:57:22 -04001645 data[et_entry] = gbe_dev->hw_stats[et_entry];
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001646 }
1647 }
1648}
1649
1650static void keystone_get_ethtool_stats(struct net_device *ndev,
1651 struct ethtool_stats *stats,
1652 uint64_t *data)
1653{
1654 struct netcp_intf *netcp = netdev_priv(ndev);
1655 struct gbe_intf *gbe_intf;
1656 struct gbe_priv *gbe_dev;
1657
1658 gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
1659 if (!gbe_intf)
1660 return;
1661
1662 gbe_dev = gbe_intf->gbe_dev;
1663 spin_lock_bh(&gbe_dev->hw_stats_lock);
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001664 if (gbe_dev->ss_version == GBE_SS_VERSION_14)
1665 gbe_update_stats_ver14(gbe_dev, data);
1666 else
1667 gbe_update_stats(gbe_dev, data);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001668 spin_unlock_bh(&gbe_dev->hw_stats_lock);
1669}
1670
1671static int keystone_get_settings(struct net_device *ndev,
1672 struct ethtool_cmd *cmd)
1673{
1674 struct netcp_intf *netcp = netdev_priv(ndev);
1675 struct phy_device *phy = ndev->phydev;
1676 struct gbe_intf *gbe_intf;
1677 int ret;
1678
1679 if (!phy)
1680 return -EINVAL;
1681
1682 gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
1683 if (!gbe_intf)
1684 return -EINVAL;
1685
1686 if (!gbe_intf->slave)
1687 return -EINVAL;
1688
1689 ret = phy_ethtool_gset(phy, cmd);
1690 if (!ret)
1691 cmd->port = gbe_intf->slave->phy_port_t;
1692
1693 return ret;
1694}
1695
1696static int keystone_set_settings(struct net_device *ndev,
1697 struct ethtool_cmd *cmd)
1698{
1699 struct netcp_intf *netcp = netdev_priv(ndev);
1700 struct phy_device *phy = ndev->phydev;
1701 struct gbe_intf *gbe_intf;
1702 u32 features = cmd->advertising & cmd->supported;
1703
1704 if (!phy)
1705 return -EINVAL;
1706
1707 gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
1708 if (!gbe_intf)
1709 return -EINVAL;
1710
1711 if (!gbe_intf->slave)
1712 return -EINVAL;
1713
1714 if (cmd->port != gbe_intf->slave->phy_port_t) {
1715 if ((cmd->port == PORT_TP) && !(features & ADVERTISED_TP))
1716 return -EINVAL;
1717
1718 if ((cmd->port == PORT_AUI) && !(features & ADVERTISED_AUI))
1719 return -EINVAL;
1720
1721 if ((cmd->port == PORT_BNC) && !(features & ADVERTISED_BNC))
1722 return -EINVAL;
1723
1724 if ((cmd->port == PORT_MII) && !(features & ADVERTISED_MII))
1725 return -EINVAL;
1726
1727 if ((cmd->port == PORT_FIBRE) && !(features & ADVERTISED_FIBRE))
1728 return -EINVAL;
1729 }
1730
1731 gbe_intf->slave->phy_port_t = cmd->port;
1732 return phy_ethtool_sset(phy, cmd);
1733}
1734
1735static const struct ethtool_ops keystone_ethtool_ops = {
1736 .get_drvinfo = keystone_get_drvinfo,
1737 .get_link = ethtool_op_get_link,
1738 .get_msglevel = keystone_get_msglevel,
1739 .set_msglevel = keystone_set_msglevel,
1740 .get_strings = keystone_get_stat_strings,
1741 .get_sset_count = keystone_get_sset_count,
1742 .get_ethtool_stats = keystone_get_ethtool_stats,
1743 .get_settings = keystone_get_settings,
1744 .set_settings = keystone_set_settings,
1745};
1746
1747#define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \
1748 ((mac)[2] << 16) | ((mac)[3] << 24))
1749#define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8))
1750
1751static void gbe_set_slave_mac(struct gbe_slave *slave,
1752 struct gbe_intf *gbe_intf)
1753{
1754 struct net_device *ndev = gbe_intf->ndev;
1755
1756 writel(mac_hi(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_hi));
1757 writel(mac_lo(ndev->dev_addr), GBE_REG_ADDR(slave, port_regs, sa_lo));
1758}
1759
1760static int gbe_get_slave_port(struct gbe_priv *priv, u32 slave_num)
1761{
1762 if (priv->host_port == 0)
1763 return slave_num + 1;
1764
1765 return slave_num;
1766}
1767
1768static void netcp_ethss_link_state_action(struct gbe_priv *gbe_dev,
1769 struct net_device *ndev,
1770 struct gbe_slave *slave,
1771 int up)
1772{
1773 struct phy_device *phy = slave->phy;
1774 u32 mac_control = 0;
1775
1776 if (up) {
1777 mac_control = slave->mac_control;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001778 if (phy && (phy->speed == SPEED_1000)) {
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001779 mac_control |= MACSL_GIG_MODE;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001780 mac_control &= ~MACSL_XGIG_MODE;
1781 } else if (phy && (phy->speed == SPEED_10000)) {
1782 mac_control |= MACSL_XGIG_MODE;
1783 mac_control &= ~MACSL_GIG_MODE;
1784 }
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001785
1786 writel(mac_control, GBE_REG_ADDR(slave, emac_regs,
1787 mac_control));
1788
1789 cpsw_ale_control_set(gbe_dev->ale, slave->port_num,
1790 ALE_PORT_STATE,
1791 ALE_PORT_STATE_FORWARD);
1792
Karicheri, Muralidharan8e046d62015-04-27 14:12:43 -04001793 if (ndev && slave->open &&
1794 slave->link_interface != SGMII_LINK_MAC_PHY &&
1795 slave->link_interface != XGMII_LINK_MAC_PHY)
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001796 netif_carrier_on(ndev);
1797 } else {
1798 writel(mac_control, GBE_REG_ADDR(slave, emac_regs,
1799 mac_control));
1800 cpsw_ale_control_set(gbe_dev->ale, slave->port_num,
1801 ALE_PORT_STATE,
1802 ALE_PORT_STATE_DISABLE);
Karicheri, Muralidharan8e046d62015-04-27 14:12:43 -04001803 if (ndev &&
1804 slave->link_interface != SGMII_LINK_MAC_PHY &&
1805 slave->link_interface != XGMII_LINK_MAC_PHY)
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001806 netif_carrier_off(ndev);
1807 }
1808
1809 if (phy)
1810 phy_print_status(phy);
1811}
1812
1813static bool gbe_phy_link_status(struct gbe_slave *slave)
1814{
1815 return !slave->phy || slave->phy->link;
1816}
1817
1818static void netcp_ethss_update_link_state(struct gbe_priv *gbe_dev,
1819 struct gbe_slave *slave,
1820 struct net_device *ndev)
1821{
1822 int sp = slave->slave_num;
1823 int phy_link_state, sgmii_link_state = 1, link_state;
1824
1825 if (!slave->open)
1826 return;
1827
WingMan Kwok9a391c72015-03-20 16:11:25 -04001828 if (!SLAVE_LINK_IS_XGMII(slave)) {
1829 if (gbe_dev->ss_version == GBE_SS_VERSION_14)
1830 sgmii_link_state =
1831 netcp_sgmii_get_port_link(SGMII_BASE(sp), sp);
1832 else
1833 sgmii_link_state =
1834 netcp_sgmii_get_port_link(
1835 gbe_dev->sgmii_port_regs, sp);
1836 }
1837
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001838 phy_link_state = gbe_phy_link_status(slave);
1839 link_state = phy_link_state & sgmii_link_state;
1840
1841 if (atomic_xchg(&slave->link_state, link_state) != link_state)
1842 netcp_ethss_link_state_action(gbe_dev, ndev, slave,
1843 link_state);
1844}
1845
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001846static void xgbe_adjust_link(struct net_device *ndev)
1847{
1848 struct netcp_intf *netcp = netdev_priv(ndev);
1849 struct gbe_intf *gbe_intf;
1850
1851 gbe_intf = netcp_module_get_intf_data(&xgbe_module, netcp);
1852 if (!gbe_intf)
1853 return;
1854
1855 netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave,
1856 ndev);
1857}
1858
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001859static void gbe_adjust_link(struct net_device *ndev)
1860{
1861 struct netcp_intf *netcp = netdev_priv(ndev);
1862 struct gbe_intf *gbe_intf;
1863
1864 gbe_intf = netcp_module_get_intf_data(&gbe_module, netcp);
1865 if (!gbe_intf)
1866 return;
1867
1868 netcp_ethss_update_link_state(gbe_intf->gbe_dev, gbe_intf->slave,
1869 ndev);
1870}
1871
1872static void gbe_adjust_link_sec_slaves(struct net_device *ndev)
1873{
1874 struct gbe_priv *gbe_dev = netdev_priv(ndev);
1875 struct gbe_slave *slave;
1876
1877 for_each_sec_slave(slave, gbe_dev)
1878 netcp_ethss_update_link_state(gbe_dev, slave, NULL);
1879}
1880
1881/* Reset EMAC
1882 * Soft reset is set and polled until clear, or until a timeout occurs
1883 */
1884static int gbe_port_reset(struct gbe_slave *slave)
1885{
1886 u32 i, v;
1887
1888 /* Set the soft reset bit */
1889 writel(SOFT_RESET, GBE_REG_ADDR(slave, emac_regs, soft_reset));
1890
1891 /* Wait for the bit to clear */
1892 for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) {
1893 v = readl(GBE_REG_ADDR(slave, emac_regs, soft_reset));
1894 if ((v & SOFT_RESET_MASK) != SOFT_RESET)
1895 return 0;
1896 }
1897
1898 /* Timeout on the reset */
1899 return GMACSL_RET_WARN_RESET_INCOMPLETE;
1900}
1901
1902/* Configure EMAC */
1903static void gbe_port_config(struct gbe_priv *gbe_dev, struct gbe_slave *slave,
1904 int max_rx_len)
1905{
WingMan Kwok9a391c72015-03-20 16:11:25 -04001906 void __iomem *rx_maxlen_reg;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001907 u32 xgmii_mode;
1908
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001909 if (max_rx_len > NETCP_MAX_FRAME_SIZE)
1910 max_rx_len = NETCP_MAX_FRAME_SIZE;
1911
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001912 /* Enable correct MII mode at SS level */
1913 if ((gbe_dev->ss_version == XGBE_SS_VERSION_10) &&
1914 (slave->link_interface >= XGMII_LINK_MAC_PHY)) {
1915 xgmii_mode = readl(GBE_REG_ADDR(gbe_dev, ss_regs, control));
1916 xgmii_mode |= (1 << slave->slave_num);
1917 writel(xgmii_mode, GBE_REG_ADDR(gbe_dev, ss_regs, control));
1918 }
1919
WingMan Kwok9a391c72015-03-20 16:11:25 -04001920 if (IS_SS_ID_MU(gbe_dev))
1921 rx_maxlen_reg = GBE_REG_ADDR(slave, port_regs, rx_maxlen);
1922 else
1923 rx_maxlen_reg = GBE_REG_ADDR(slave, emac_regs, rx_maxlen);
1924
1925 writel(max_rx_len, rx_maxlen_reg);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001926 writel(slave->mac_control, GBE_REG_ADDR(slave, emac_regs, mac_control));
1927}
1928
1929static void gbe_slave_stop(struct gbe_intf *intf)
1930{
1931 struct gbe_priv *gbe_dev = intf->gbe_dev;
1932 struct gbe_slave *slave = intf->slave;
1933
1934 gbe_port_reset(slave);
1935 /* Disable forwarding */
1936 cpsw_ale_control_set(gbe_dev->ale, slave->port_num,
1937 ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
1938 cpsw_ale_del_mcast(gbe_dev->ale, intf->ndev->broadcast,
1939 1 << slave->port_num, 0, 0);
1940
1941 if (!slave->phy)
1942 return;
1943
1944 phy_stop(slave->phy);
1945 phy_disconnect(slave->phy);
1946 slave->phy = NULL;
1947}
1948
1949static void gbe_sgmii_config(struct gbe_priv *priv, struct gbe_slave *slave)
1950{
1951 void __iomem *sgmii_port_regs;
1952
1953 sgmii_port_regs = priv->sgmii_port_regs;
1954 if ((priv->ss_version == GBE_SS_VERSION_14) && (slave->slave_num >= 2))
1955 sgmii_port_regs = priv->sgmii_port34_regs;
1956
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001957 if (!SLAVE_LINK_IS_XGMII(slave)) {
1958 netcp_sgmii_reset(sgmii_port_regs, slave->slave_num);
1959 netcp_sgmii_config(sgmii_port_regs, slave->slave_num,
1960 slave->link_interface);
1961 }
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001962}
1963
1964static int gbe_slave_open(struct gbe_intf *gbe_intf)
1965{
1966 struct gbe_priv *priv = gbe_intf->gbe_dev;
1967 struct gbe_slave *slave = gbe_intf->slave;
1968 phy_interface_t phy_mode;
1969 bool has_phy = false;
1970
1971 void (*hndlr)(struct net_device *) = gbe_adjust_link;
1972
1973 gbe_sgmii_config(priv, slave);
1974 gbe_port_reset(slave);
1975 gbe_port_config(priv, slave, priv->rx_packet_max);
1976 gbe_set_slave_mac(slave, gbe_intf);
1977 /* enable forwarding */
1978 cpsw_ale_control_set(priv->ale, slave->port_num,
1979 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
1980 cpsw_ale_add_mcast(priv->ale, gbe_intf->ndev->broadcast,
1981 1 << slave->port_num, 0, 0, ALE_MCAST_FWD_2);
1982
1983 if (slave->link_interface == SGMII_LINK_MAC_PHY) {
1984 has_phy = true;
1985 phy_mode = PHY_INTERFACE_MODE_SGMII;
1986 slave->phy_port_t = PORT_MII;
1987 } else if (slave->link_interface == XGMII_LINK_MAC_PHY) {
1988 has_phy = true;
1989 phy_mode = PHY_INTERFACE_MODE_NA;
1990 slave->phy_port_t = PORT_FIBRE;
1991 }
1992
1993 if (has_phy) {
Wingman Kwok90cff9e2015-01-15 19:12:52 -05001994 if (priv->ss_version == XGBE_SS_VERSION_10)
1995 hndlr = xgbe_adjust_link;
1996
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05001997 slave->phy = of_phy_connect(gbe_intf->ndev,
1998 slave->phy_node,
1999 hndlr, 0,
2000 phy_mode);
2001 if (!slave->phy) {
2002 dev_err(priv->dev, "phy not found on slave %d\n",
2003 slave->slave_num);
2004 return -ENODEV;
2005 }
2006 dev_dbg(priv->dev, "phy found: id is: 0x%s\n",
2007 dev_name(&slave->phy->dev));
2008 phy_start(slave->phy);
2009 phy_read_status(slave->phy);
2010 }
2011 return 0;
2012}
2013
2014static void gbe_init_host_port(struct gbe_priv *priv)
2015{
2016 int bypass_en = 1;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002017
2018 /* Host Tx Pri */
2019 if (IS_SS_ID_NU(priv))
2020 writel(HOST_TX_PRI_MAP_DEFAULT,
2021 GBE_REG_ADDR(priv, host_port_regs, tx_pri_map));
2022
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002023 /* Max length register */
2024 writel(NETCP_MAX_FRAME_SIZE, GBE_REG_ADDR(priv, host_port_regs,
2025 rx_maxlen));
2026
2027 cpsw_ale_start(priv->ale);
2028
2029 if (priv->enable_ale)
2030 bypass_en = 0;
2031
2032 cpsw_ale_control_set(priv->ale, 0, ALE_BYPASS, bypass_en);
2033
2034 cpsw_ale_control_set(priv->ale, 0, ALE_NO_PORT_VLAN, 1);
2035
2036 cpsw_ale_control_set(priv->ale, priv->host_port,
2037 ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
2038
2039 cpsw_ale_control_set(priv->ale, 0,
2040 ALE_PORT_UNKNOWN_VLAN_MEMBER,
2041 GBE_PORT_MASK(priv->ale_ports));
2042
2043 cpsw_ale_control_set(priv->ale, 0,
2044 ALE_PORT_UNKNOWN_MCAST_FLOOD,
2045 GBE_PORT_MASK(priv->ale_ports - 1));
2046
2047 cpsw_ale_control_set(priv->ale, 0,
2048 ALE_PORT_UNKNOWN_REG_MCAST_FLOOD,
2049 GBE_PORT_MASK(priv->ale_ports));
2050
2051 cpsw_ale_control_set(priv->ale, 0,
2052 ALE_PORT_UNTAGGED_EGRESS,
2053 GBE_PORT_MASK(priv->ale_ports));
2054}
2055
2056static void gbe_add_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr)
2057{
2058 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2059 u16 vlan_id;
2060
2061 cpsw_ale_add_mcast(gbe_dev->ale, addr,
2062 GBE_PORT_MASK(gbe_dev->ale_ports), 0, 0,
2063 ALE_MCAST_FWD_2);
2064 for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) {
2065 cpsw_ale_add_mcast(gbe_dev->ale, addr,
2066 GBE_PORT_MASK(gbe_dev->ale_ports),
2067 ALE_VLAN, vlan_id, ALE_MCAST_FWD_2);
2068 }
2069}
2070
2071static void gbe_add_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr)
2072{
2073 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2074 u16 vlan_id;
2075
2076 cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0);
2077
2078 for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID)
2079 cpsw_ale_add_ucast(gbe_dev->ale, addr, gbe_dev->host_port,
2080 ALE_VLAN, vlan_id);
2081}
2082
2083static void gbe_del_mcast_addr(struct gbe_intf *gbe_intf, u8 *addr)
2084{
2085 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2086 u16 vlan_id;
2087
2088 cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, 0, 0);
2089
2090 for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) {
2091 cpsw_ale_del_mcast(gbe_dev->ale, addr, 0, ALE_VLAN, vlan_id);
2092 }
2093}
2094
2095static void gbe_del_ucast_addr(struct gbe_intf *gbe_intf, u8 *addr)
2096{
2097 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2098 u16 vlan_id;
2099
2100 cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port, 0, 0);
2101
2102 for_each_set_bit(vlan_id, gbe_intf->active_vlans, VLAN_N_VID) {
2103 cpsw_ale_del_ucast(gbe_dev->ale, addr, gbe_dev->host_port,
2104 ALE_VLAN, vlan_id);
2105 }
2106}
2107
2108static int gbe_add_addr(void *intf_priv, struct netcp_addr *naddr)
2109{
2110 struct gbe_intf *gbe_intf = intf_priv;
2111 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2112
2113 dev_dbg(gbe_dev->dev, "ethss adding address %pM, type %d\n",
2114 naddr->addr, naddr->type);
2115
2116 switch (naddr->type) {
2117 case ADDR_MCAST:
2118 case ADDR_BCAST:
2119 gbe_add_mcast_addr(gbe_intf, naddr->addr);
2120 break;
2121 case ADDR_UCAST:
2122 case ADDR_DEV:
2123 gbe_add_ucast_addr(gbe_intf, naddr->addr);
2124 break;
2125 case ADDR_ANY:
2126 /* nothing to do for promiscuous */
2127 default:
2128 break;
2129 }
2130
2131 return 0;
2132}
2133
2134static int gbe_del_addr(void *intf_priv, struct netcp_addr *naddr)
2135{
2136 struct gbe_intf *gbe_intf = intf_priv;
2137 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2138
2139 dev_dbg(gbe_dev->dev, "ethss deleting address %pM, type %d\n",
2140 naddr->addr, naddr->type);
2141
2142 switch (naddr->type) {
2143 case ADDR_MCAST:
2144 case ADDR_BCAST:
2145 gbe_del_mcast_addr(gbe_intf, naddr->addr);
2146 break;
2147 case ADDR_UCAST:
2148 case ADDR_DEV:
2149 gbe_del_ucast_addr(gbe_intf, naddr->addr);
2150 break;
2151 case ADDR_ANY:
2152 /* nothing to do for promiscuous */
2153 default:
2154 break;
2155 }
2156
2157 return 0;
2158}
2159
2160static int gbe_add_vid(void *intf_priv, int vid)
2161{
2162 struct gbe_intf *gbe_intf = intf_priv;
2163 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2164
2165 set_bit(vid, gbe_intf->active_vlans);
2166
2167 cpsw_ale_add_vlan(gbe_dev->ale, vid,
2168 GBE_PORT_MASK(gbe_dev->ale_ports),
2169 GBE_MASK_NO_PORTS,
2170 GBE_PORT_MASK(gbe_dev->ale_ports),
2171 GBE_PORT_MASK(gbe_dev->ale_ports - 1));
2172
2173 return 0;
2174}
2175
2176static int gbe_del_vid(void *intf_priv, int vid)
2177{
2178 struct gbe_intf *gbe_intf = intf_priv;
2179 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2180
2181 cpsw_ale_del_vlan(gbe_dev->ale, vid, 0);
2182 clear_bit(vid, gbe_intf->active_vlans);
2183 return 0;
2184}
2185
2186static int gbe_ioctl(void *intf_priv, struct ifreq *req, int cmd)
2187{
2188 struct gbe_intf *gbe_intf = intf_priv;
2189 struct phy_device *phy = gbe_intf->slave->phy;
2190 int ret = -EOPNOTSUPP;
2191
2192 if (phy)
2193 ret = phy_mii_ioctl(phy, req, cmd);
2194
2195 return ret;
2196}
2197
2198static void netcp_ethss_timer(unsigned long arg)
2199{
2200 struct gbe_priv *gbe_dev = (struct gbe_priv *)arg;
2201 struct gbe_intf *gbe_intf;
2202 struct gbe_slave *slave;
2203
2204 /* Check & update SGMII link state of interfaces */
2205 for_each_intf(gbe_intf, gbe_dev) {
2206 if (!gbe_intf->slave->open)
2207 continue;
2208 netcp_ethss_update_link_state(gbe_dev, gbe_intf->slave,
2209 gbe_intf->ndev);
2210 }
2211
2212 /* Check & update SGMII link state of secondary ports */
2213 for_each_sec_slave(slave, gbe_dev) {
2214 netcp_ethss_update_link_state(gbe_dev, slave, NULL);
2215 }
2216
WingMan Kwokc0f54ed2015-07-23 15:57:19 -04002217 /* A timer runs as a BH, no need to block them */
2218 spin_lock(&gbe_dev->hw_stats_lock);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002219
2220 if (gbe_dev->ss_version == GBE_SS_VERSION_14)
2221 gbe_update_stats_ver14(gbe_dev, NULL);
2222 else
2223 gbe_update_stats(gbe_dev, NULL);
2224
WingMan Kwokc0f54ed2015-07-23 15:57:19 -04002225 spin_unlock(&gbe_dev->hw_stats_lock);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002226
2227 gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL;
2228 add_timer(&gbe_dev->timer);
2229}
2230
2231static int gbe_tx_hook(int order, void *data, struct netcp_packet *p_info)
2232{
2233 struct gbe_intf *gbe_intf = data;
2234
2235 p_info->tx_pipe = &gbe_intf->tx_pipe;
2236 return 0;
2237}
2238
2239static int gbe_open(void *intf_priv, struct net_device *ndev)
2240{
2241 struct gbe_intf *gbe_intf = intf_priv;
2242 struct gbe_priv *gbe_dev = gbe_intf->gbe_dev;
2243 struct netcp_intf *netcp = netdev_priv(ndev);
2244 struct gbe_slave *slave = gbe_intf->slave;
2245 int port_num = slave->port_num;
2246 u32 reg;
2247 int ret;
2248
2249 reg = readl(GBE_REG_ADDR(gbe_dev, switch_regs, id_ver));
2250 dev_dbg(gbe_dev->dev, "initializing gbe version %d.%d (%d) GBE identification value 0x%x\n",
2251 GBE_MAJOR_VERSION(reg), GBE_MINOR_VERSION(reg),
2252 GBE_RTL_VERSION(reg), GBE_IDENT(reg));
2253
WingMan Kwok9a391c72015-03-20 16:11:25 -04002254 /* For 10G and on NetCP 1.5, use directed to port */
2255 if ((gbe_dev->ss_version == XGBE_SS_VERSION_10) || IS_SS_ID_MU(gbe_dev))
Karicheri, Muralidharane170f402015-03-20 16:11:21 -04002256 gbe_intf->tx_pipe.flags = SWITCH_TO_PORT_IN_TAGINFO;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002257
Karicheri, Muralidharane170f402015-03-20 16:11:21 -04002258 if (gbe_dev->enable_ale)
2259 gbe_intf->tx_pipe.switch_to_port = 0;
2260 else
2261 gbe_intf->tx_pipe.switch_to_port = port_num;
2262
2263 dev_dbg(gbe_dev->dev,
2264 "opened TX channel %s: %p with to port %d, flags %d\n",
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002265 gbe_intf->tx_pipe.dma_chan_name,
2266 gbe_intf->tx_pipe.dma_channel,
Karicheri, Muralidharane170f402015-03-20 16:11:21 -04002267 gbe_intf->tx_pipe.switch_to_port,
2268 gbe_intf->tx_pipe.flags);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002269
2270 gbe_slave_stop(gbe_intf);
2271
2272 /* disable priority elevation and enable statistics on all ports */
2273 writel(0, GBE_REG_ADDR(gbe_dev, switch_regs, ptype));
2274
2275 /* Control register */
2276 writel(GBE_CTL_P0_ENABLE, GBE_REG_ADDR(gbe_dev, switch_regs, control));
2277
2278 /* All statistics enabled and STAT AB visible by default */
WingMan Kwok9a391c72015-03-20 16:11:25 -04002279 writel(gbe_dev->stats_en_mask, GBE_REG_ADDR(gbe_dev, switch_regs,
2280 stat_port_en));
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002281
2282 ret = gbe_slave_open(gbe_intf);
2283 if (ret)
2284 goto fail;
2285
2286 netcp_register_txhook(netcp, GBE_TXHOOK_ORDER, gbe_tx_hook,
2287 gbe_intf);
2288
2289 slave->open = true;
2290 netcp_ethss_update_link_state(gbe_dev, slave, ndev);
2291 return 0;
2292
2293fail:
2294 gbe_slave_stop(gbe_intf);
2295 return ret;
2296}
2297
2298static int gbe_close(void *intf_priv, struct net_device *ndev)
2299{
2300 struct gbe_intf *gbe_intf = intf_priv;
2301 struct netcp_intf *netcp = netdev_priv(ndev);
2302
2303 gbe_slave_stop(gbe_intf);
2304 netcp_unregister_txhook(netcp, GBE_TXHOOK_ORDER, gbe_tx_hook,
2305 gbe_intf);
2306
2307 gbe_intf->slave->open = false;
2308 atomic_set(&gbe_intf->slave->link_state, NETCP_LINK_STATE_INVALID);
2309 return 0;
2310}
2311
2312static int init_slave(struct gbe_priv *gbe_dev, struct gbe_slave *slave,
2313 struct device_node *node)
2314{
2315 int port_reg_num;
2316 u32 port_reg_ofs, emac_reg_ofs;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002317 u32 port_reg_blk_sz, emac_reg_blk_sz;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002318
2319 if (of_property_read_u32(node, "slave-port", &slave->slave_num)) {
2320 dev_err(gbe_dev->dev, "missing slave-port parameter\n");
2321 return -EINVAL;
2322 }
2323
2324 if (of_property_read_u32(node, "link-interface",
2325 &slave->link_interface)) {
2326 dev_warn(gbe_dev->dev,
2327 "missing link-interface value defaulting to 1G mac-phy link\n");
2328 slave->link_interface = SGMII_LINK_MAC_PHY;
2329 }
2330
2331 slave->open = false;
2332 slave->phy_node = of_parse_phandle(node, "phy-handle", 0);
2333 slave->port_num = gbe_get_slave_port(gbe_dev, slave->slave_num);
2334
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002335 if (slave->link_interface >= XGMII_LINK_MAC_PHY)
2336 slave->mac_control = GBE_DEF_10G_MAC_CONTROL;
2337 else
2338 slave->mac_control = GBE_DEF_1G_MAC_CONTROL;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002339
2340 /* Emac regs memmap are contiguous but port regs are not */
2341 port_reg_num = slave->slave_num;
2342 if (gbe_dev->ss_version == GBE_SS_VERSION_14) {
2343 if (slave->slave_num > 1) {
2344 port_reg_ofs = GBE13_SLAVE_PORT2_OFFSET;
2345 port_reg_num -= 2;
2346 } else {
2347 port_reg_ofs = GBE13_SLAVE_PORT_OFFSET;
2348 }
WingMan Kwok9a391c72015-03-20 16:11:25 -04002349 emac_reg_ofs = GBE13_EMAC_OFFSET;
2350 port_reg_blk_sz = 0x30;
2351 emac_reg_blk_sz = 0x40;
2352 } else if (IS_SS_ID_MU(gbe_dev)) {
2353 port_reg_ofs = GBENU_SLAVE_PORT_OFFSET;
2354 emac_reg_ofs = GBENU_EMAC_OFFSET;
2355 port_reg_blk_sz = 0x1000;
2356 emac_reg_blk_sz = 0x1000;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002357 } else if (gbe_dev->ss_version == XGBE_SS_VERSION_10) {
2358 port_reg_ofs = XGBE10_SLAVE_PORT_OFFSET;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002359 emac_reg_ofs = XGBE10_EMAC_OFFSET;
2360 port_reg_blk_sz = 0x30;
2361 emac_reg_blk_sz = 0x40;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002362 } else {
2363 dev_err(gbe_dev->dev, "unknown ethss(0x%x)\n",
2364 gbe_dev->ss_version);
2365 return -EINVAL;
2366 }
2367
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002368 slave->port_regs = gbe_dev->switch_regs + port_reg_ofs +
WingMan Kwok9a391c72015-03-20 16:11:25 -04002369 (port_reg_blk_sz * port_reg_num);
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002370 slave->emac_regs = gbe_dev->switch_regs + emac_reg_ofs +
WingMan Kwok9a391c72015-03-20 16:11:25 -04002371 (emac_reg_blk_sz * slave->slave_num);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002372
2373 if (gbe_dev->ss_version == GBE_SS_VERSION_14) {
2374 /* Initialize slave port register offsets */
2375 GBE_SET_REG_OFS(slave, port_regs, port_vlan);
2376 GBE_SET_REG_OFS(slave, port_regs, tx_pri_map);
2377 GBE_SET_REG_OFS(slave, port_regs, sa_lo);
2378 GBE_SET_REG_OFS(slave, port_regs, sa_hi);
2379 GBE_SET_REG_OFS(slave, port_regs, ts_ctl);
2380 GBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype);
2381 GBE_SET_REG_OFS(slave, port_regs, ts_vlan);
2382 GBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2);
2383 GBE_SET_REG_OFS(slave, port_regs, ts_ctl2);
2384
2385 /* Initialize EMAC register offsets */
2386 GBE_SET_REG_OFS(slave, emac_regs, mac_control);
2387 GBE_SET_REG_OFS(slave, emac_regs, soft_reset);
2388 GBE_SET_REG_OFS(slave, emac_regs, rx_maxlen);
2389
WingMan Kwok9a391c72015-03-20 16:11:25 -04002390 } else if (IS_SS_ID_MU(gbe_dev)) {
2391 /* Initialize slave port register offsets */
2392 GBENU_SET_REG_OFS(slave, port_regs, port_vlan);
2393 GBENU_SET_REG_OFS(slave, port_regs, tx_pri_map);
2394 GBENU_SET_REG_OFS(slave, port_regs, sa_lo);
2395 GBENU_SET_REG_OFS(slave, port_regs, sa_hi);
2396 GBENU_SET_REG_OFS(slave, port_regs, ts_ctl);
2397 GBENU_SET_REG_OFS(slave, port_regs, ts_seq_ltype);
2398 GBENU_SET_REG_OFS(slave, port_regs, ts_vlan);
2399 GBENU_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2);
2400 GBENU_SET_REG_OFS(slave, port_regs, ts_ctl2);
2401 GBENU_SET_REG_OFS(slave, port_regs, rx_maxlen);
2402
2403 /* Initialize EMAC register offsets */
2404 GBENU_SET_REG_OFS(slave, emac_regs, mac_control);
2405 GBENU_SET_REG_OFS(slave, emac_regs, soft_reset);
2406
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002407 } else if (gbe_dev->ss_version == XGBE_SS_VERSION_10) {
2408 /* Initialize slave port register offsets */
2409 XGBE_SET_REG_OFS(slave, port_regs, port_vlan);
2410 XGBE_SET_REG_OFS(slave, port_regs, tx_pri_map);
2411 XGBE_SET_REG_OFS(slave, port_regs, sa_lo);
2412 XGBE_SET_REG_OFS(slave, port_regs, sa_hi);
2413 XGBE_SET_REG_OFS(slave, port_regs, ts_ctl);
2414 XGBE_SET_REG_OFS(slave, port_regs, ts_seq_ltype);
2415 XGBE_SET_REG_OFS(slave, port_regs, ts_vlan);
2416 XGBE_SET_REG_OFS(slave, port_regs, ts_ctl_ltype2);
2417 XGBE_SET_REG_OFS(slave, port_regs, ts_ctl2);
2418
2419 /* Initialize EMAC register offsets */
2420 XGBE_SET_REG_OFS(slave, emac_regs, mac_control);
2421 XGBE_SET_REG_OFS(slave, emac_regs, soft_reset);
2422 XGBE_SET_REG_OFS(slave, emac_regs, rx_maxlen);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002423 }
2424
2425 atomic_set(&slave->link_state, NETCP_LINK_STATE_INVALID);
2426 return 0;
2427}
2428
2429static void init_secondary_ports(struct gbe_priv *gbe_dev,
2430 struct device_node *node)
2431{
2432 struct device *dev = gbe_dev->dev;
2433 phy_interface_t phy_mode;
2434 struct gbe_priv **priv;
2435 struct device_node *port;
2436 struct gbe_slave *slave;
2437 bool mac_phy_link = false;
2438
2439 for_each_child_of_node(node, port) {
2440 slave = devm_kzalloc(dev, sizeof(*slave), GFP_KERNEL);
2441 if (!slave) {
2442 dev_err(dev,
2443 "memomry alloc failed for secondary port(%s), skipping...\n",
2444 port->name);
2445 continue;
2446 }
2447
2448 if (init_slave(gbe_dev, slave, port)) {
2449 dev_err(dev,
2450 "Failed to initialize secondary port(%s), skipping...\n",
2451 port->name);
2452 devm_kfree(dev, slave);
2453 continue;
2454 }
2455
2456 gbe_sgmii_config(gbe_dev, slave);
2457 gbe_port_reset(slave);
2458 gbe_port_config(gbe_dev, slave, gbe_dev->rx_packet_max);
2459 list_add_tail(&slave->slave_list, &gbe_dev->secondary_slaves);
2460 gbe_dev->num_slaves++;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002461 if ((slave->link_interface == SGMII_LINK_MAC_PHY) ||
2462 (slave->link_interface == XGMII_LINK_MAC_PHY))
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002463 mac_phy_link = true;
2464
2465 slave->open = true;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002466 if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves)
2467 break;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002468 }
2469
2470 /* of_phy_connect() is needed only for MAC-PHY interface */
2471 if (!mac_phy_link)
2472 return;
2473
2474 /* Allocate dummy netdev device for attaching to phy device */
2475 gbe_dev->dummy_ndev = alloc_netdev(sizeof(gbe_dev), "dummy",
2476 NET_NAME_UNKNOWN, ether_setup);
2477 if (!gbe_dev->dummy_ndev) {
2478 dev_err(dev,
2479 "Failed to allocate dummy netdev for secondary ports, skipping phy_connect()...\n");
2480 return;
2481 }
2482 priv = netdev_priv(gbe_dev->dummy_ndev);
2483 *priv = gbe_dev;
2484
2485 if (slave->link_interface == SGMII_LINK_MAC_PHY) {
2486 phy_mode = PHY_INTERFACE_MODE_SGMII;
2487 slave->phy_port_t = PORT_MII;
2488 } else {
2489 phy_mode = PHY_INTERFACE_MODE_NA;
2490 slave->phy_port_t = PORT_FIBRE;
2491 }
2492
2493 for_each_sec_slave(slave, gbe_dev) {
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002494 if ((slave->link_interface != SGMII_LINK_MAC_PHY) &&
2495 (slave->link_interface != XGMII_LINK_MAC_PHY))
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002496 continue;
2497 slave->phy =
2498 of_phy_connect(gbe_dev->dummy_ndev,
2499 slave->phy_node,
2500 gbe_adjust_link_sec_slaves,
2501 0, phy_mode);
2502 if (!slave->phy) {
2503 dev_err(dev, "phy not found for slave %d\n",
2504 slave->slave_num);
2505 slave->phy = NULL;
2506 } else {
2507 dev_dbg(dev, "phy found: id is: 0x%s\n",
2508 dev_name(&slave->phy->dev));
2509 phy_start(slave->phy);
2510 phy_read_status(slave->phy);
2511 }
2512 }
2513}
2514
2515static void free_secondary_ports(struct gbe_priv *gbe_dev)
2516{
2517 struct gbe_slave *slave;
2518
2519 for (;;) {
2520 slave = first_sec_slave(gbe_dev);
2521 if (!slave)
2522 break;
2523 if (slave->phy)
2524 phy_disconnect(slave->phy);
2525 list_del(&slave->slave_list);
2526 }
2527 if (gbe_dev->dummy_ndev)
2528 free_netdev(gbe_dev->dummy_ndev);
2529}
2530
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002531static int set_xgbe_ethss10_priv(struct gbe_priv *gbe_dev,
2532 struct device_node *node)
2533{
2534 struct resource res;
2535 void __iomem *regs;
2536 int ret, i;
2537
WingMan Kwok9a391c72015-03-20 16:11:25 -04002538 ret = of_address_to_resource(node, XGBE_SS_REG_INDEX, &res);
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002539 if (ret) {
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002540 dev_err(gbe_dev->dev,
2541 "Can't xlate xgbe of node(%s) ss address at %d\n",
2542 node->name, XGBE_SS_REG_INDEX);
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002543 return ret;
2544 }
2545
2546 regs = devm_ioremap_resource(gbe_dev->dev, &res);
2547 if (IS_ERR(regs)) {
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002548 dev_err(gbe_dev->dev, "Failed to map xgbe ss register base\n");
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002549 return PTR_ERR(regs);
2550 }
2551 gbe_dev->ss_regs = regs;
2552
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002553 ret = of_address_to_resource(node, XGBE_SM_REG_INDEX, &res);
2554 if (ret) {
2555 dev_err(gbe_dev->dev,
2556 "Can't xlate xgbe of node(%s) sm address at %d\n",
2557 node->name, XGBE_SM_REG_INDEX);
2558 return ret;
2559 }
2560
2561 regs = devm_ioremap_resource(gbe_dev->dev, &res);
2562 if (IS_ERR(regs)) {
2563 dev_err(gbe_dev->dev, "Failed to map xgbe sm register base\n");
2564 return PTR_ERR(regs);
2565 }
2566 gbe_dev->switch_regs = regs;
2567
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002568 ret = of_address_to_resource(node, XGBE_SERDES_REG_INDEX, &res);
2569 if (ret) {
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002570 dev_err(gbe_dev->dev,
2571 "Can't xlate xgbe serdes of node(%s) address at %d\n",
2572 node->name, XGBE_SERDES_REG_INDEX);
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002573 return ret;
2574 }
2575
2576 regs = devm_ioremap_resource(gbe_dev->dev, &res);
2577 if (IS_ERR(regs)) {
2578 dev_err(gbe_dev->dev, "Failed to map xgbe serdes register base\n");
2579 return PTR_ERR(regs);
2580 }
2581 gbe_dev->xgbe_serdes_regs = regs;
2582
WingMan Kwok489e8a22015-07-23 15:57:23 -04002583 gbe_dev->num_stats_mods = gbe_dev->max_num_ports;
WingMan Kwok208c6b92015-07-23 15:57:21 -04002584 gbe_dev->et_stats = xgbe10_et_stats;
2585 gbe_dev->num_et_stats = ARRAY_SIZE(xgbe10_et_stats);
2586
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002587 gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
WingMan Kwok208c6b92015-07-23 15:57:21 -04002588 gbe_dev->num_et_stats * sizeof(u64),
2589 GFP_KERNEL);
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002590 if (!gbe_dev->hw_stats) {
2591 dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
2592 return -ENOMEM;
2593 }
2594
WingMan Kwok489e8a22015-07-23 15:57:23 -04002595 gbe_dev->hw_stats_prev =
2596 devm_kzalloc(gbe_dev->dev,
2597 gbe_dev->num_et_stats * sizeof(u32),
2598 GFP_KERNEL);
2599 if (!gbe_dev->hw_stats_prev) {
2600 dev_err(gbe_dev->dev,
2601 "hw_stats_prev memory allocation failed\n");
2602 return -ENOMEM;
2603 }
2604
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002605 gbe_dev->ss_version = XGBE_SS_VERSION_10;
2606 gbe_dev->sgmii_port_regs = gbe_dev->ss_regs +
2607 XGBE10_SGMII_MODULE_OFFSET;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002608 gbe_dev->host_port_regs = gbe_dev->ss_regs + XGBE10_HOST_PORT_OFFSET;
2609
WingMan Kwok9a391c72015-03-20 16:11:25 -04002610 for (i = 0; i < gbe_dev->max_num_ports; i++)
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002611 gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs +
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002612 XGBE10_HW_STATS_OFFSET + (GBE_HW_STATS_REG_MAP_SZ * i);
2613
WingMan Kwok9a391c72015-03-20 16:11:25 -04002614 gbe_dev->ale_reg = gbe_dev->switch_regs + XGBE10_ALE_OFFSET;
2615 gbe_dev->ale_ports = gbe_dev->max_num_ports;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002616 gbe_dev->host_port = XGBE10_HOST_PORT_NUM;
2617 gbe_dev->ale_entries = XGBE10_NUM_ALE_ENTRIES;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002618 gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002619
2620 /* Subsystem registers */
2621 XGBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver);
2622 XGBE_SET_REG_OFS(gbe_dev, ss_regs, control);
2623
2624 /* Switch module registers */
2625 XGBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver);
2626 XGBE_SET_REG_OFS(gbe_dev, switch_regs, control);
2627 XGBE_SET_REG_OFS(gbe_dev, switch_regs, ptype);
2628 XGBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en);
2629 XGBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control);
2630
2631 /* Host port registers */
2632 XGBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan);
2633 XGBE_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map);
2634 XGBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen);
2635 return 0;
2636}
2637
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002638static int get_gbe_resource_version(struct gbe_priv *gbe_dev,
2639 struct device_node *node)
2640{
2641 struct resource res;
2642 void __iomem *regs;
2643 int ret;
2644
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002645 ret = of_address_to_resource(node, GBE_SS_REG_INDEX, &res);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002646 if (ret) {
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002647 dev_err(gbe_dev->dev,
2648 "Can't translate of node(%s) of gbe ss address at %d\n",
2649 node->name, GBE_SS_REG_INDEX);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002650 return ret;
2651 }
2652
2653 regs = devm_ioremap_resource(gbe_dev->dev, &res);
2654 if (IS_ERR(regs)) {
2655 dev_err(gbe_dev->dev, "Failed to map gbe register base\n");
2656 return PTR_ERR(regs);
2657 }
2658 gbe_dev->ss_regs = regs;
2659 gbe_dev->ss_version = readl(gbe_dev->ss_regs);
2660 return 0;
2661}
2662
2663static int set_gbe_ethss14_priv(struct gbe_priv *gbe_dev,
2664 struct device_node *node)
2665{
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002666 struct resource res;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002667 void __iomem *regs;
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002668 int i, ret;
2669
2670 ret = of_address_to_resource(node, GBE_SGMII34_REG_INDEX, &res);
2671 if (ret) {
2672 dev_err(gbe_dev->dev,
2673 "Can't translate of gbe node(%s) address at index %d\n",
2674 node->name, GBE_SGMII34_REG_INDEX);
2675 return ret;
2676 }
2677
2678 regs = devm_ioremap_resource(gbe_dev->dev, &res);
2679 if (IS_ERR(regs)) {
2680 dev_err(gbe_dev->dev,
2681 "Failed to map gbe sgmii port34 register base\n");
2682 return PTR_ERR(regs);
2683 }
2684 gbe_dev->sgmii_port34_regs = regs;
2685
2686 ret = of_address_to_resource(node, GBE_SM_REG_INDEX, &res);
2687 if (ret) {
2688 dev_err(gbe_dev->dev,
2689 "Can't translate of gbe node(%s) address at index %d\n",
2690 node->name, GBE_SM_REG_INDEX);
2691 return ret;
2692 }
2693
2694 regs = devm_ioremap_resource(gbe_dev->dev, &res);
2695 if (IS_ERR(regs)) {
2696 dev_err(gbe_dev->dev,
2697 "Failed to map gbe switch module register base\n");
2698 return PTR_ERR(regs);
2699 }
2700 gbe_dev->switch_regs = regs;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002701
WingMan Kwok489e8a22015-07-23 15:57:23 -04002702 gbe_dev->num_stats_mods = gbe_dev->max_num_slaves;
WingMan Kwok208c6b92015-07-23 15:57:21 -04002703 gbe_dev->et_stats = gbe13_et_stats;
2704 gbe_dev->num_et_stats = ARRAY_SIZE(gbe13_et_stats);
2705
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002706 gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
WingMan Kwok208c6b92015-07-23 15:57:21 -04002707 gbe_dev->num_et_stats * sizeof(u64),
2708 GFP_KERNEL);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002709 if (!gbe_dev->hw_stats) {
2710 dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
2711 return -ENOMEM;
2712 }
2713
WingMan Kwok489e8a22015-07-23 15:57:23 -04002714 gbe_dev->hw_stats_prev =
2715 devm_kzalloc(gbe_dev->dev,
2716 gbe_dev->num_et_stats * sizeof(u32),
2717 GFP_KERNEL);
2718 if (!gbe_dev->hw_stats_prev) {
2719 dev_err(gbe_dev->dev,
2720 "hw_stats_prev memory allocation failed\n");
2721 return -ENOMEM;
2722 }
2723
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002724 gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBE13_SGMII_MODULE_OFFSET;
2725 gbe_dev->host_port_regs = gbe_dev->switch_regs + GBE13_HOST_PORT_OFFSET;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002726
WingMan Kwoka94bcd092015-07-23 15:57:20 -04002727 /* K2HK has only 2 hw stats modules visible at a time, so
2728 * module 0 & 2 points to one base and
2729 * module 1 & 3 points to the other base
2730 */
WingMan Kwok9a391c72015-03-20 16:11:25 -04002731 for (i = 0; i < gbe_dev->max_num_slaves; i++) {
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002732 gbe_dev->hw_stats_regs[i] =
2733 gbe_dev->switch_regs + GBE13_HW_STATS_OFFSET +
WingMan Kwoka94bcd092015-07-23 15:57:20 -04002734 (GBE_HW_STATS_REG_MAP_SZ * (i & 0x1));
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002735 }
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002736
Karicheri, Muralidharan21e0e0d2015-03-20 16:11:22 -04002737 gbe_dev->ale_reg = gbe_dev->switch_regs + GBE13_ALE_OFFSET;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002738 gbe_dev->ale_ports = gbe_dev->max_num_ports;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002739 gbe_dev->host_port = GBE13_HOST_PORT_NUM;
2740 gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002741 gbe_dev->stats_en_mask = GBE13_REG_VAL_STAT_ENABLE_ALL;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002742
2743 /* Subsystem registers */
2744 GBE_SET_REG_OFS(gbe_dev, ss_regs, id_ver);
2745
2746 /* Switch module registers */
2747 GBE_SET_REG_OFS(gbe_dev, switch_regs, id_ver);
2748 GBE_SET_REG_OFS(gbe_dev, switch_regs, control);
2749 GBE_SET_REG_OFS(gbe_dev, switch_regs, soft_reset);
2750 GBE_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en);
2751 GBE_SET_REG_OFS(gbe_dev, switch_regs, ptype);
2752 GBE_SET_REG_OFS(gbe_dev, switch_regs, flow_control);
2753
2754 /* Host port registers */
2755 GBE_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan);
2756 GBE_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen);
2757 return 0;
2758}
2759
WingMan Kwok9a391c72015-03-20 16:11:25 -04002760static int set_gbenu_ethss_priv(struct gbe_priv *gbe_dev,
2761 struct device_node *node)
2762{
2763 struct resource res;
2764 void __iomem *regs;
2765 int i, ret;
2766
WingMan Kwok489e8a22015-07-23 15:57:23 -04002767 gbe_dev->num_stats_mods = gbe_dev->max_num_ports;
WingMan Kwok208c6b92015-07-23 15:57:21 -04002768 gbe_dev->et_stats = gbenu_et_stats;
2769
2770 if (IS_SS_ID_NU(gbe_dev))
2771 gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE +
2772 (gbe_dev->max_num_slaves * GBENU_ET_STATS_PORT_SIZE);
2773 else
2774 gbe_dev->num_et_stats = GBENU_ET_STATS_HOST_SIZE +
2775 GBENU_ET_STATS_PORT_SIZE;
2776
WingMan Kwok9a391c72015-03-20 16:11:25 -04002777 gbe_dev->hw_stats = devm_kzalloc(gbe_dev->dev,
WingMan Kwok208c6b92015-07-23 15:57:21 -04002778 gbe_dev->num_et_stats * sizeof(u64),
2779 GFP_KERNEL);
WingMan Kwok9a391c72015-03-20 16:11:25 -04002780 if (!gbe_dev->hw_stats) {
2781 dev_err(gbe_dev->dev, "hw_stats memory allocation failed\n");
2782 return -ENOMEM;
2783 }
2784
WingMan Kwok489e8a22015-07-23 15:57:23 -04002785 gbe_dev->hw_stats_prev =
2786 devm_kzalloc(gbe_dev->dev,
2787 gbe_dev->num_et_stats * sizeof(u32),
2788 GFP_KERNEL);
2789 if (!gbe_dev->hw_stats_prev) {
2790 dev_err(gbe_dev->dev,
2791 "hw_stats_prev memory allocation failed\n");
2792 return -ENOMEM;
2793 }
2794
WingMan Kwok9a391c72015-03-20 16:11:25 -04002795 ret = of_address_to_resource(node, GBENU_SM_REG_INDEX, &res);
2796 if (ret) {
2797 dev_err(gbe_dev->dev,
2798 "Can't translate of gbenu node(%s) addr at index %d\n",
2799 node->name, GBENU_SM_REG_INDEX);
2800 return ret;
2801 }
2802
2803 regs = devm_ioremap_resource(gbe_dev->dev, &res);
2804 if (IS_ERR(regs)) {
2805 dev_err(gbe_dev->dev,
2806 "Failed to map gbenu switch module register base\n");
2807 return PTR_ERR(regs);
2808 }
2809 gbe_dev->switch_regs = regs;
2810
2811 gbe_dev->sgmii_port_regs = gbe_dev->ss_regs + GBENU_SGMII_MODULE_OFFSET;
2812 gbe_dev->host_port_regs = gbe_dev->switch_regs + GBENU_HOST_PORT_OFFSET;
2813
2814 for (i = 0; i < (gbe_dev->max_num_ports); i++)
2815 gbe_dev->hw_stats_regs[i] = gbe_dev->switch_regs +
2816 GBENU_HW_STATS_OFFSET + (GBENU_HW_STATS_REG_MAP_SZ * i);
2817
2818 gbe_dev->ale_reg = gbe_dev->switch_regs + GBENU_ALE_OFFSET;
2819 gbe_dev->ale_ports = gbe_dev->max_num_ports;
2820 gbe_dev->host_port = GBENU_HOST_PORT_NUM;
2821 gbe_dev->ale_entries = GBE13_NUM_ALE_ENTRIES;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002822 gbe_dev->stats_en_mask = (1 << (gbe_dev->max_num_ports)) - 1;
2823
WingMan Kwok9a391c72015-03-20 16:11:25 -04002824 /* Subsystem registers */
2825 GBENU_SET_REG_OFS(gbe_dev, ss_regs, id_ver);
2826
2827 /* Switch module registers */
2828 GBENU_SET_REG_OFS(gbe_dev, switch_regs, id_ver);
2829 GBENU_SET_REG_OFS(gbe_dev, switch_regs, control);
2830 GBENU_SET_REG_OFS(gbe_dev, switch_regs, stat_port_en);
2831 GBENU_SET_REG_OFS(gbe_dev, switch_regs, ptype);
2832
2833 /* Host port registers */
2834 GBENU_SET_REG_OFS(gbe_dev, host_port_regs, port_vlan);
2835 GBENU_SET_REG_OFS(gbe_dev, host_port_regs, rx_maxlen);
2836
2837 /* For NU only. 2U does not need tx_pri_map.
2838 * NU cppi port 0 tx pkt streaming interface has (n-1)*8 egress threads
2839 * while 2U has only 1 such thread
2840 */
2841 GBENU_SET_REG_OFS(gbe_dev, host_port_regs, tx_pri_map);
2842 return 0;
2843}
2844
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002845static int gbe_probe(struct netcp_device *netcp_device, struct device *dev,
2846 struct device_node *node, void **inst_priv)
2847{
2848 struct device_node *interfaces, *interface;
2849 struct device_node *secondary_ports;
2850 struct cpsw_ale_params ale_params;
2851 struct gbe_priv *gbe_dev;
2852 u32 slave_num;
WingMan Kwok489e8a22015-07-23 15:57:23 -04002853 int i, ret = 0;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002854
2855 if (!node) {
2856 dev_err(dev, "device tree info unavailable\n");
2857 return -ENODEV;
2858 }
2859
2860 gbe_dev = devm_kzalloc(dev, sizeof(struct gbe_priv), GFP_KERNEL);
2861 if (!gbe_dev)
2862 return -ENOMEM;
2863
WingMan Kwok9a391c72015-03-20 16:11:25 -04002864 if (of_device_is_compatible(node, "ti,netcp-gbe-5") ||
2865 of_device_is_compatible(node, "ti,netcp-gbe")) {
2866 gbe_dev->max_num_slaves = 4;
2867 } else if (of_device_is_compatible(node, "ti,netcp-gbe-9")) {
2868 gbe_dev->max_num_slaves = 8;
2869 } else if (of_device_is_compatible(node, "ti,netcp-gbe-2")) {
2870 gbe_dev->max_num_slaves = 1;
2871 } else if (of_device_is_compatible(node, "ti,netcp-xgbe")) {
2872 gbe_dev->max_num_slaves = 2;
2873 } else {
2874 dev_err(dev, "device tree node for unknown device\n");
2875 return -EINVAL;
2876 }
2877 gbe_dev->max_num_ports = gbe_dev->max_num_slaves + 1;
2878
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002879 gbe_dev->dev = dev;
2880 gbe_dev->netcp_device = netcp_device;
2881 gbe_dev->rx_packet_max = NETCP_MAX_FRAME_SIZE;
2882
2883 /* init the hw stats lock */
2884 spin_lock_init(&gbe_dev->hw_stats_lock);
2885
2886 if (of_find_property(node, "enable-ale", NULL)) {
2887 gbe_dev->enable_ale = true;
2888 dev_info(dev, "ALE enabled\n");
2889 } else {
2890 gbe_dev->enable_ale = false;
2891 dev_dbg(dev, "ALE bypass enabled*\n");
2892 }
2893
2894 ret = of_property_read_u32(node, "tx-queue",
2895 &gbe_dev->tx_queue_id);
2896 if (ret < 0) {
2897 dev_err(dev, "missing tx_queue parameter\n");
2898 gbe_dev->tx_queue_id = GBE_TX_QUEUE;
2899 }
2900
2901 ret = of_property_read_string(node, "tx-channel",
2902 &gbe_dev->dma_chan_name);
2903 if (ret < 0) {
2904 dev_err(dev, "missing \"tx-channel\" parameter\n");
2905 ret = -ENODEV;
2906 goto quit;
2907 }
2908
2909 if (!strcmp(node->name, "gbe")) {
2910 ret = get_gbe_resource_version(gbe_dev, node);
2911 if (ret)
2912 goto quit;
2913
WingMan Kwok9a391c72015-03-20 16:11:25 -04002914 dev_dbg(dev, "ss_version: 0x%08x\n", gbe_dev->ss_version);
2915
2916 if (gbe_dev->ss_version == GBE_SS_VERSION_14)
2917 ret = set_gbe_ethss14_priv(gbe_dev, node);
2918 else if (IS_SS_ID_MU(gbe_dev))
2919 ret = set_gbenu_ethss_priv(gbe_dev, node);
2920 else
2921 ret = -ENODEV;
2922
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002923 if (ret)
2924 goto quit;
Wingman Kwok90cff9e2015-01-15 19:12:52 -05002925 } else if (!strcmp(node->name, "xgbe")) {
2926 ret = set_xgbe_ethss10_priv(gbe_dev, node);
2927 if (ret)
2928 goto quit;
2929 ret = netcp_xgbe_serdes_init(gbe_dev->xgbe_serdes_regs,
2930 gbe_dev->ss_regs);
2931 if (ret)
2932 goto quit;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002933 } else {
2934 dev_err(dev, "unknown GBE node(%s)\n", node->name);
2935 ret = -ENODEV;
2936 goto quit;
2937 }
2938
2939 interfaces = of_get_child_by_name(node, "interfaces");
2940 if (!interfaces)
2941 dev_err(dev, "could not find interfaces\n");
2942
2943 ret = netcp_txpipe_init(&gbe_dev->tx_pipe, netcp_device,
2944 gbe_dev->dma_chan_name, gbe_dev->tx_queue_id);
2945 if (ret)
2946 goto quit;
2947
2948 ret = netcp_txpipe_open(&gbe_dev->tx_pipe);
2949 if (ret)
2950 goto quit;
2951
2952 /* Create network interfaces */
2953 INIT_LIST_HEAD(&gbe_dev->gbe_intf_head);
2954 for_each_child_of_node(interfaces, interface) {
2955 ret = of_property_read_u32(interface, "slave-port", &slave_num);
2956 if (ret) {
2957 dev_err(dev, "missing slave-port parameter, skipping interface configuration for %s\n",
2958 interface->name);
2959 continue;
2960 }
2961 gbe_dev->num_slaves++;
WingMan Kwok9a391c72015-03-20 16:11:25 -04002962 if (gbe_dev->num_slaves >= gbe_dev->max_num_slaves)
2963 break;
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002964 }
2965
2966 if (!gbe_dev->num_slaves)
2967 dev_warn(dev, "No network interface configured\n");
2968
2969 /* Initialize Secondary slave ports */
2970 secondary_ports = of_get_child_by_name(node, "secondary-slave-ports");
2971 INIT_LIST_HEAD(&gbe_dev->secondary_slaves);
WingMan Kwok9a391c72015-03-20 16:11:25 -04002972 if (secondary_ports && (gbe_dev->num_slaves < gbe_dev->max_num_slaves))
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05002973 init_secondary_ports(gbe_dev, secondary_ports);
2974 of_node_put(secondary_ports);
2975
2976 if (!gbe_dev->num_slaves) {
2977 dev_err(dev, "No network interface or secondary ports configured\n");
2978 ret = -ENODEV;
2979 goto quit;
2980 }
2981
2982 memset(&ale_params, 0, sizeof(ale_params));
2983 ale_params.dev = gbe_dev->dev;
2984 ale_params.ale_regs = gbe_dev->ale_reg;
2985 ale_params.ale_ageout = GBE_DEFAULT_ALE_AGEOUT;
2986 ale_params.ale_entries = gbe_dev->ale_entries;
2987 ale_params.ale_ports = gbe_dev->ale_ports;
2988
2989 gbe_dev->ale = cpsw_ale_create(&ale_params);
2990 if (!gbe_dev->ale) {
2991 dev_err(gbe_dev->dev, "error initializing ale engine\n");
2992 ret = -ENODEV;
2993 goto quit;
2994 } else {
2995 dev_dbg(gbe_dev->dev, "Created a gbe ale engine\n");
2996 }
2997
2998 /* initialize host port */
2999 gbe_init_host_port(gbe_dev);
3000
WingMan Kwok489e8a22015-07-23 15:57:23 -04003001 spin_lock_bh(&gbe_dev->hw_stats_lock);
3002 for (i = 0; i < gbe_dev->num_stats_mods; i++) {
3003 if (gbe_dev->ss_version == GBE_SS_VERSION_14)
3004 gbe_reset_mod_stats_ver14(gbe_dev, i);
3005 else
3006 gbe_reset_mod_stats(gbe_dev, i);
3007 }
3008 spin_unlock_bh(&gbe_dev->hw_stats_lock);
3009
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05003010 init_timer(&gbe_dev->timer);
3011 gbe_dev->timer.data = (unsigned long)gbe_dev;
3012 gbe_dev->timer.function = netcp_ethss_timer;
3013 gbe_dev->timer.expires = jiffies + GBE_TIMER_INTERVAL;
3014 add_timer(&gbe_dev->timer);
3015 *inst_priv = gbe_dev;
3016 return 0;
3017
3018quit:
3019 if (gbe_dev->hw_stats)
3020 devm_kfree(dev, gbe_dev->hw_stats);
WingMan Kwok489e8a22015-07-23 15:57:23 -04003021 if (gbe_dev->hw_stats_prev)
3022 devm_kfree(dev, gbe_dev->hw_stats_prev);
Markus Elfring9b556692015-02-03 20:12:25 +01003023 cpsw_ale_destroy(gbe_dev->ale);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05003024 if (gbe_dev->ss_regs)
3025 devm_iounmap(dev, gbe_dev->ss_regs);
Markus Elfring9b556692015-02-03 20:12:25 +01003026 of_node_put(interfaces);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05003027 devm_kfree(dev, gbe_dev);
3028 return ret;
3029}
3030
3031static int gbe_attach(void *inst_priv, struct net_device *ndev,
3032 struct device_node *node, void **intf_priv)
3033{
3034 struct gbe_priv *gbe_dev = inst_priv;
3035 struct gbe_intf *gbe_intf;
3036 int ret;
3037
3038 if (!node) {
3039 dev_err(gbe_dev->dev, "interface node not available\n");
3040 return -ENODEV;
3041 }
3042
3043 gbe_intf = devm_kzalloc(gbe_dev->dev, sizeof(*gbe_intf), GFP_KERNEL);
3044 if (!gbe_intf)
3045 return -ENOMEM;
3046
3047 gbe_intf->ndev = ndev;
3048 gbe_intf->dev = gbe_dev->dev;
3049 gbe_intf->gbe_dev = gbe_dev;
3050
3051 gbe_intf->slave = devm_kzalloc(gbe_dev->dev,
3052 sizeof(*gbe_intf->slave),
3053 GFP_KERNEL);
3054 if (!gbe_intf->slave) {
3055 ret = -ENOMEM;
3056 goto fail;
3057 }
3058
3059 if (init_slave(gbe_dev, gbe_intf->slave, node)) {
3060 ret = -ENODEV;
3061 goto fail;
3062 }
3063
3064 gbe_intf->tx_pipe = gbe_dev->tx_pipe;
3065 ndev->ethtool_ops = &keystone_ethtool_ops;
3066 list_add_tail(&gbe_intf->gbe_intf_list, &gbe_dev->gbe_intf_head);
3067 *intf_priv = gbe_intf;
3068 return 0;
3069
3070fail:
3071 if (gbe_intf->slave)
3072 devm_kfree(gbe_dev->dev, gbe_intf->slave);
3073 if (gbe_intf)
3074 devm_kfree(gbe_dev->dev, gbe_intf);
3075 return ret;
3076}
3077
3078static int gbe_release(void *intf_priv)
3079{
3080 struct gbe_intf *gbe_intf = intf_priv;
3081
3082 gbe_intf->ndev->ethtool_ops = NULL;
3083 list_del(&gbe_intf->gbe_intf_list);
3084 devm_kfree(gbe_intf->dev, gbe_intf->slave);
3085 devm_kfree(gbe_intf->dev, gbe_intf);
3086 return 0;
3087}
3088
3089static int gbe_remove(struct netcp_device *netcp_device, void *inst_priv)
3090{
3091 struct gbe_priv *gbe_dev = inst_priv;
3092
3093 del_timer_sync(&gbe_dev->timer);
3094 cpsw_ale_stop(gbe_dev->ale);
3095 cpsw_ale_destroy(gbe_dev->ale);
3096 netcp_txpipe_close(&gbe_dev->tx_pipe);
3097 free_secondary_ports(gbe_dev);
3098
3099 if (!list_empty(&gbe_dev->gbe_intf_head))
3100 dev_alert(gbe_dev->dev, "unreleased ethss interfaces present\n");
3101
3102 devm_kfree(gbe_dev->dev, gbe_dev->hw_stats);
3103 devm_iounmap(gbe_dev->dev, gbe_dev->ss_regs);
3104 memset(gbe_dev, 0x00, sizeof(*gbe_dev));
3105 devm_kfree(gbe_dev->dev, gbe_dev);
3106 return 0;
3107}
3108
3109static struct netcp_module gbe_module = {
3110 .name = GBE_MODULE_NAME,
3111 .owner = THIS_MODULE,
3112 .primary = true,
3113 .probe = gbe_probe,
3114 .open = gbe_open,
3115 .close = gbe_close,
3116 .remove = gbe_remove,
3117 .attach = gbe_attach,
3118 .release = gbe_release,
3119 .add_addr = gbe_add_addr,
3120 .del_addr = gbe_del_addr,
3121 .add_vid = gbe_add_vid,
3122 .del_vid = gbe_del_vid,
3123 .ioctl = gbe_ioctl,
3124};
3125
Wingman Kwok90cff9e2015-01-15 19:12:52 -05003126static struct netcp_module xgbe_module = {
3127 .name = XGBE_MODULE_NAME,
3128 .owner = THIS_MODULE,
3129 .primary = true,
3130 .probe = gbe_probe,
3131 .open = gbe_open,
3132 .close = gbe_close,
3133 .remove = gbe_remove,
3134 .attach = gbe_attach,
3135 .release = gbe_release,
3136 .add_addr = gbe_add_addr,
3137 .del_addr = gbe_del_addr,
3138 .add_vid = gbe_add_vid,
3139 .del_vid = gbe_del_vid,
3140 .ioctl = gbe_ioctl,
3141};
3142
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05003143static int __init keystone_gbe_init(void)
3144{
3145 int ret;
3146
3147 ret = netcp_register_module(&gbe_module);
3148 if (ret)
3149 return ret;
3150
Wingman Kwok90cff9e2015-01-15 19:12:52 -05003151 ret = netcp_register_module(&xgbe_module);
3152 if (ret)
3153 return ret;
3154
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05003155 return 0;
3156}
3157module_init(keystone_gbe_init);
3158
3159static void __exit keystone_gbe_exit(void)
3160{
3161 netcp_unregister_module(&gbe_module);
Wingman Kwok90cff9e2015-01-15 19:12:52 -05003162 netcp_unregister_module(&xgbe_module);
Wingman Kwok6f8d3f32015-01-15 19:12:51 -05003163}
3164module_exit(keystone_gbe_exit);
Karicheri, Muralidharan58c11b52015-01-29 18:15:51 -05003165
3166MODULE_LICENSE("GPL v2");
3167MODULE_DESCRIPTION("TI NETCP ETHSS driver for Keystone SOCs");
3168MODULE_AUTHOR("Sandeep Nair <sandeep_n@ti.com");