Commit | Line | Data |
---|---|---|
8585bdad | 1 | // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-or-later |
57ba4c9b | 2 | /* |
8585bdad | 3 | * Copyright 2008 - 2015 Freescale Semiconductor Inc. |
57ba4c9b IL |
4 | */ |
5 | ||
6 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | |
7 | ||
8 | #include "fman_memac.h" | |
9 | #include "fman.h" | |
302376fe | 10 | #include "mac.h" |
57ba4c9b IL |
11 | |
12 | #include <linux/slab.h> | |
13 | #include <linux/io.h> | |
a7c2a32e | 14 | #include <linux/pcs-lynx.h> |
57ba4c9b | 15 | #include <linux/phy.h> |
f225e4e6 | 16 | #include <linux/phy_fixed.h> |
0fc83bd7 | 17 | #include <linux/phy/phy.h> |
57ba4c9b IL |
18 | #include <linux/of_mdio.h> |
19 | ||
57ba4c9b IL |
20 | /* Num of additional exact match MAC adr regs */ |
21 | #define MEMAC_NUM_OF_PADDRS 7 | |
22 | ||
23 | /* Control and Configuration Register (COMMAND_CONFIG) */ | |
24 | #define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */ | |
25 | #define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */ | |
26 | #define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */ | |
27 | #define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */ | |
28 | #define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */ | |
29 | #define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */ | |
30 | #define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */ | |
31 | #define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */ | |
32 | #define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */ | |
33 | #define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */ | |
34 | #define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */ | |
35 | #define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */ | |
36 | ||
37 | /* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */ | |
38 | #define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000 | |
39 | #define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF | |
40 | #define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000 | |
41 | #define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000 | |
42 | #define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019 | |
43 | #define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020 | |
44 | #define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060 | |
45 | ||
46 | #define GET_TX_EMPTY_DEFAULT_VALUE(_val) \ | |
47 | do { \ | |
48 | _val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \ | |
49 | ((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \ | |
50 | (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) :\ | |
51 | (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));\ | |
52 | } while (0) | |
53 | ||
54 | /* Interface Mode Register (IF_MODE) */ | |
55 | ||
56 | #define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */ | |
457bfc0a | 57 | #define IF_MODE_10G 0x00000000 /* 30-31 10G interface */ |
5bc8f5ab | 58 | #define IF_MODE_MII 0x00000001 /* 30-31 MII interface */ |
57ba4c9b IL |
59 | #define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */ |
60 | #define IF_MODE_RGMII 0x00000004 | |
61 | #define IF_MODE_RGMII_AUTO 0x00008000 | |
62 | #define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */ | |
63 | #define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */ | |
64 | #define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */ | |
65 | #define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */ | |
66 | #define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */ | |
67 | #define IF_MODE_HD 0x00000040 /* Half duplex operation */ | |
68 | ||
69 | /* Hash table Control Register (HASHTABLE_CTRL) */ | |
70 | #define HASH_CTRL_MCAST_EN 0x00000100 | |
71 | /* 26-31 Hash table address code */ | |
72 | #define HASH_CTRL_ADDR_MASK 0x0000003F | |
73 | /* MAC mcast indication */ | |
74 | #define GROUP_ADDRESS 0x0000010000000000LL | |
75 | #define HASH_TABLE_SIZE 64 /* Hash tbl size */ | |
76 | ||
77 | /* Interrupt Mask Register (IMASK) */ | |
78 | #define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */ | |
79 | #define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */ | |
80 | #define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */ | |
81 | #define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */ | |
82 | ||
83 | #define MEMAC_ALL_ERRS_IMASK \ | |
84 | ((u32)(MEMAC_IMASK_TSECC_ER | \ | |
85 | MEMAC_IMASK_TECC_ER | \ | |
86 | MEMAC_IMASK_RECC_ER | \ | |
87 | MEMAC_IMASK_MGI)) | |
88 | ||
89 | #define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */ | |
90 | #define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */ | |
91 | #define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */ | |
92 | #define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */ | |
93 | #define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error*/ | |
94 | #define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */ | |
95 | #define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */ | |
96 | #define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */ | |
97 | #define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */ | |
98 | #define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */ | |
99 | #define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */ | |
100 | #define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */ | |
101 | #define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */ | |
102 | #define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */ | |
103 | #define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */ | |
104 | #define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */ | |
105 | #define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */ | |
106 | ||
107 | #define DEFAULT_PAUSE_QUANTA 0xf000 | |
108 | #define DEFAULT_FRAME_LENGTH 0x600 | |
109 | #define DEFAULT_TX_IPG_LENGTH 12 | |
110 | ||
111 | #define CLXY_PAUSE_QUANTA_CLX_PQNT 0x0000FFFF | |
112 | #define CLXY_PAUSE_QUANTA_CLY_PQNT 0xFFFF0000 | |
113 | #define CLXY_PAUSE_THRESH_CLX_QTH 0x0000FFFF | |
114 | #define CLXY_PAUSE_THRESH_CLY_QTH 0xFFFF0000 | |
115 | ||
116 | struct mac_addr { | |
117 | /* Lower 32 bits of 48-bit MAC address */ | |
118 | u32 mac_addr_l; | |
119 | /* Upper 16 bits of 48-bit MAC address */ | |
120 | u32 mac_addr_u; | |
121 | }; | |
122 | ||
123 | /* memory map */ | |
124 | struct memac_regs { | |
125 | u32 res0000[2]; /* General Control and Status */ | |
126 | u32 command_config; /* 0x008 Ctrl and cfg */ | |
127 | struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */ | |
128 | u32 maxfrm; /* 0x014 Max frame length */ | |
129 | u32 res0018[1]; | |
130 | u32 rx_fifo_sections; /* Receive FIFO configuration reg */ | |
131 | u32 tx_fifo_sections; /* Transmit FIFO configuration reg */ | |
132 | u32 res0024[2]; | |
133 | u32 hashtable_ctrl; /* 0x02C Hash table control */ | |
134 | u32 res0030[4]; | |
135 | u32 ievent; /* 0x040 Interrupt event */ | |
136 | u32 tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */ | |
137 | u32 res0048; | |
138 | u32 imask; /* 0x04C Interrupt mask */ | |
139 | u32 res0050; | |
140 | u32 pause_quanta[4]; /* 0x054 Pause quanta */ | |
141 | u32 pause_thresh[4]; /* 0x064 Pause quanta threshold */ | |
142 | u32 rx_pause_status; /* 0x074 Receive pause status */ | |
143 | u32 res0078[2]; | |
144 | struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS];/* 0x80-0x0B4 mac padr */ | |
145 | u32 lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */ | |
146 | u32 sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */ | |
147 | u32 res00c0[8]; | |
148 | u32 statn_config; /* 0x0E0 Statistics configuration */ | |
149 | u32 res00e4[7]; | |
150 | /* Rx Statistics Counter */ | |
151 | u32 reoct_l; | |
152 | u32 reoct_u; | |
153 | u32 roct_l; | |
154 | u32 roct_u; | |
155 | u32 raln_l; | |
156 | u32 raln_u; | |
157 | u32 rxpf_l; | |
158 | u32 rxpf_u; | |
159 | u32 rfrm_l; | |
160 | u32 rfrm_u; | |
161 | u32 rfcs_l; | |
162 | u32 rfcs_u; | |
163 | u32 rvlan_l; | |
164 | u32 rvlan_u; | |
165 | u32 rerr_l; | |
166 | u32 rerr_u; | |
167 | u32 ruca_l; | |
168 | u32 ruca_u; | |
169 | u32 rmca_l; | |
170 | u32 rmca_u; | |
171 | u32 rbca_l; | |
172 | u32 rbca_u; | |
173 | u32 rdrp_l; | |
174 | u32 rdrp_u; | |
175 | u32 rpkt_l; | |
176 | u32 rpkt_u; | |
177 | u32 rund_l; | |
178 | u32 rund_u; | |
179 | u32 r64_l; | |
180 | u32 r64_u; | |
181 | u32 r127_l; | |
182 | u32 r127_u; | |
183 | u32 r255_l; | |
184 | u32 r255_u; | |
185 | u32 r511_l; | |
186 | u32 r511_u; | |
187 | u32 r1023_l; | |
188 | u32 r1023_u; | |
189 | u32 r1518_l; | |
190 | u32 r1518_u; | |
191 | u32 r1519x_l; | |
192 | u32 r1519x_u; | |
193 | u32 rovr_l; | |
194 | u32 rovr_u; | |
195 | u32 rjbr_l; | |
196 | u32 rjbr_u; | |
197 | u32 rfrg_l; | |
198 | u32 rfrg_u; | |
199 | u32 rcnp_l; | |
200 | u32 rcnp_u; | |
201 | u32 rdrntp_l; | |
202 | u32 rdrntp_u; | |
203 | u32 res01d0[12]; | |
204 | /* Tx Statistics Counter */ | |
205 | u32 teoct_l; | |
206 | u32 teoct_u; | |
207 | u32 toct_l; | |
208 | u32 toct_u; | |
209 | u32 res0210[2]; | |
210 | u32 txpf_l; | |
211 | u32 txpf_u; | |
212 | u32 tfrm_l; | |
213 | u32 tfrm_u; | |
214 | u32 tfcs_l; | |
215 | u32 tfcs_u; | |
216 | u32 tvlan_l; | |
217 | u32 tvlan_u; | |
218 | u32 terr_l; | |
219 | u32 terr_u; | |
220 | u32 tuca_l; | |
221 | u32 tuca_u; | |
222 | u32 tmca_l; | |
223 | u32 tmca_u; | |
224 | u32 tbca_l; | |
225 | u32 tbca_u; | |
226 | u32 res0258[2]; | |
227 | u32 tpkt_l; | |
228 | u32 tpkt_u; | |
229 | u32 tund_l; | |
230 | u32 tund_u; | |
231 | u32 t64_l; | |
232 | u32 t64_u; | |
233 | u32 t127_l; | |
234 | u32 t127_u; | |
235 | u32 t255_l; | |
236 | u32 t255_u; | |
237 | u32 t511_l; | |
238 | u32 t511_u; | |
239 | u32 t1023_l; | |
240 | u32 t1023_u; | |
241 | u32 t1518_l; | |
242 | u32 t1518_u; | |
243 | u32 t1519x_l; | |
244 | u32 t1519x_u; | |
245 | u32 res02a8[6]; | |
246 | u32 tcnp_l; | |
247 | u32 tcnp_u; | |
248 | u32 res02c8[14]; | |
249 | /* Line Interface Control */ | |
250 | u32 if_mode; /* 0x300 Interface Mode Control */ | |
251 | u32 if_status; /* 0x304 Interface Status */ | |
252 | u32 res0308[14]; | |
253 | /* HiGig/2 */ | |
254 | u32 hg_config; /* 0x340 Control and cfg */ | |
255 | u32 res0344[3]; | |
256 | u32 hg_pause_quanta; /* 0x350 Pause quanta */ | |
257 | u32 res0354[3]; | |
258 | u32 hg_pause_thresh; /* 0x360 Pause quanta threshold */ | |
259 | u32 res0364[3]; | |
260 | u32 hgrx_pause_status; /* 0x370 Receive pause status */ | |
261 | u32 hg_fifos_status; /* 0x374 fifos status */ | |
262 | u32 rhm; /* 0x378 rx messages counter */ | |
263 | u32 thm; /* 0x37C tx messages counter */ | |
264 | }; | |
265 | ||
266 | struct memac_cfg { | |
267 | bool reset_on_init; | |
268 | bool pause_ignore; | |
269 | bool promiscuous_mode_enable; | |
270 | struct fixed_phy_status *fixed_link; | |
271 | u16 max_frame_length; | |
272 | u16 pause_quanta; | |
273 | u32 tx_ipg_length; | |
274 | }; | |
275 | ||
276 | struct fman_mac { | |
277 | /* Pointer to MAC memory mapped registers */ | |
278 | struct memac_regs __iomem *regs; | |
279 | /* MAC address of device */ | |
280 | u64 addr; | |
5b6acb55 | 281 | struct mac_device *dev_id; /* device cookie used by the exception cbs */ |
57ba4c9b IL |
282 | fman_mac_exception_cb *exception_cb; |
283 | fman_mac_exception_cb *event_cb; | |
284 | /* Pointer to driver's global address hash table */ | |
285 | struct eth_hash_t *multicast_addr_hash; | |
286 | /* Pointer to driver's individual address hash table */ | |
287 | struct eth_hash_t *unicast_addr_hash; | |
288 | u8 mac_id; | |
289 | u32 exceptions; | |
290 | struct memac_cfg *memac_drv_param; | |
291 | void *fm; | |
292 | struct fman_rev_info fm_rev_info; | |
0fc83bd7 | 293 | struct phy *serdes; |
a7c2a32e SA |
294 | struct phylink_pcs *sgmii_pcs; |
295 | struct phylink_pcs *qsgmii_pcs; | |
296 | struct phylink_pcs *xfi_pcs; | |
c893238e | 297 | bool allmulti_enabled; |
5d93cfcf | 298 | bool rgmii_no_half_duplex; |
57ba4c9b IL |
299 | }; |
300 | ||
76660757 | 301 | static void add_addr_in_paddr(struct memac_regs __iomem *regs, const u8 *adr, |
57ba4c9b IL |
302 | u8 paddr_num) |
303 | { | |
304 | u32 tmp0, tmp1; | |
305 | ||
306 | tmp0 = (u32)(adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24); | |
307 | tmp1 = (u32)(adr[4] | adr[5] << 8); | |
308 | ||
309 | if (paddr_num == 0) { | |
310 | iowrite32be(tmp0, ®s->mac_addr0.mac_addr_l); | |
311 | iowrite32be(tmp1, ®s->mac_addr0.mac_addr_u); | |
312 | } else { | |
313 | iowrite32be(tmp0, ®s->mac_addr[paddr_num - 1].mac_addr_l); | |
314 | iowrite32be(tmp1, ®s->mac_addr[paddr_num - 1].mac_addr_u); | |
315 | } | |
316 | } | |
317 | ||
318 | static int reset(struct memac_regs __iomem *regs) | |
319 | { | |
320 | u32 tmp; | |
321 | int count; | |
322 | ||
323 | tmp = ioread32be(®s->command_config); | |
324 | ||
325 | tmp |= CMD_CFG_SW_RESET; | |
326 | ||
327 | iowrite32be(tmp, ®s->command_config); | |
328 | ||
329 | count = 100; | |
330 | do { | |
331 | udelay(1); | |
332 | } while ((ioread32be(®s->command_config) & CMD_CFG_SW_RESET) && | |
333 | --count); | |
334 | ||
335 | if (count == 0) | |
336 | return -EBUSY; | |
337 | ||
338 | return 0; | |
339 | } | |
340 | ||
341 | static void set_exception(struct memac_regs __iomem *regs, u32 val, | |
342 | bool enable) | |
343 | { | |
344 | u32 tmp; | |
345 | ||
346 | tmp = ioread32be(®s->imask); | |
347 | if (enable) | |
348 | tmp |= val; | |
349 | else | |
350 | tmp &= ~val; | |
351 | ||
352 | iowrite32be(tmp, ®s->imask); | |
353 | } | |
354 | ||
355 | static int init(struct memac_regs __iomem *regs, struct memac_cfg *cfg, | |
57ba4c9b IL |
356 | u32 exceptions) |
357 | { | |
358 | u32 tmp; | |
359 | ||
360 | /* Config */ | |
361 | tmp = 0; | |
362 | if (cfg->promiscuous_mode_enable) | |
363 | tmp |= CMD_CFG_PROMIS_EN; | |
364 | if (cfg->pause_ignore) | |
365 | tmp |= CMD_CFG_PAUSE_IGNORE; | |
366 | ||
367 | /* Payload length check disable */ | |
368 | tmp |= CMD_CFG_NO_LEN_CHK; | |
369 | /* Enable padding of frames in transmit direction */ | |
370 | tmp |= CMD_CFG_TX_PAD_EN; | |
371 | ||
372 | tmp |= CMD_CFG_CRC_FWD; | |
373 | ||
374 | iowrite32be(tmp, ®s->command_config); | |
375 | ||
376 | /* Max Frame Length */ | |
377 | iowrite32be((u32)cfg->max_frame_length, ®s->maxfrm); | |
378 | ||
379 | /* Pause Time */ | |
380 | iowrite32be((u32)cfg->pause_quanta, ®s->pause_quanta[0]); | |
381 | iowrite32be((u32)0, ®s->pause_thresh[0]); | |
382 | ||
57ba4c9b IL |
383 | /* clear all pending events and set-up interrupts */ |
384 | iowrite32be(0xffffffff, ®s->ievent); | |
385 | set_exception(regs, exceptions, true); | |
386 | ||
387 | return 0; | |
388 | } | |
389 | ||
390 | static void set_dflts(struct memac_cfg *cfg) | |
391 | { | |
392 | cfg->reset_on_init = false; | |
393 | cfg->promiscuous_mode_enable = false; | |
394 | cfg->pause_ignore = false; | |
395 | cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH; | |
396 | cfg->max_frame_length = DEFAULT_FRAME_LENGTH; | |
397 | cfg->pause_quanta = DEFAULT_PAUSE_QUANTA; | |
398 | } | |
399 | ||
400 | static u32 get_mac_addr_hash_code(u64 eth_addr) | |
401 | { | |
402 | u64 mask1, mask2; | |
403 | u32 xor_val = 0; | |
404 | u8 i, j; | |
405 | ||
406 | for (i = 0; i < 6; i++) { | |
407 | mask1 = eth_addr & (u64)0x01; | |
408 | eth_addr >>= 1; | |
409 | ||
410 | for (j = 0; j < 7; j++) { | |
411 | mask2 = eth_addr & (u64)0x01; | |
412 | mask1 ^= mask2; | |
413 | eth_addr >>= 1; | |
414 | } | |
415 | ||
416 | xor_val |= (mask1 << (5 - i)); | |
417 | } | |
418 | ||
419 | return xor_val; | |
420 | } | |
421 | ||
57ba4c9b IL |
422 | static int check_init_parameters(struct fman_mac *memac) |
423 | { | |
57ba4c9b IL |
424 | if (!memac->exception_cb) { |
425 | pr_err("Uninitialized exception handler\n"); | |
426 | return -EINVAL; | |
427 | } | |
428 | if (!memac->event_cb) { | |
429 | pr_warn("Uninitialize event handler\n"); | |
430 | return -EINVAL; | |
431 | } | |
432 | ||
433 | return 0; | |
434 | } | |
435 | ||
436 | static int get_exception_flag(enum fman_mac_exceptions exception) | |
437 | { | |
438 | u32 bit_mask; | |
439 | ||
440 | switch (exception) { | |
441 | case FM_MAC_EX_10G_TX_ECC_ER: | |
442 | bit_mask = MEMAC_IMASK_TECC_ER; | |
443 | break; | |
444 | case FM_MAC_EX_10G_RX_ECC_ER: | |
445 | bit_mask = MEMAC_IMASK_RECC_ER; | |
446 | break; | |
447 | case FM_MAC_EX_TS_FIFO_ECC_ERR: | |
448 | bit_mask = MEMAC_IMASK_TSECC_ER; | |
449 | break; | |
450 | case FM_MAC_EX_MAGIC_PACKET_INDICATION: | |
451 | bit_mask = MEMAC_IMASK_MGI; | |
452 | break; | |
453 | default: | |
454 | bit_mask = 0; | |
455 | break; | |
456 | } | |
457 | ||
458 | return bit_mask; | |
459 | } | |
460 | ||
461 | static void memac_err_exception(void *handle) | |
462 | { | |
463 | struct fman_mac *memac = (struct fman_mac *)handle; | |
464 | struct memac_regs __iomem *regs = memac->regs; | |
465 | u32 event, imask; | |
466 | ||
467 | event = ioread32be(®s->ievent); | |
468 | imask = ioread32be(®s->imask); | |
469 | ||
470 | /* Imask include both error and notification/event bits. | |
471 | * Leaving only error bits enabled by imask. | |
472 | * The imask error bits are shifted by 16 bits offset from | |
473 | * their corresponding location in the ievent - hence the >> 16 | |
474 | */ | |
475 | event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); | |
476 | ||
477 | iowrite32be(event, ®s->ievent); | |
478 | ||
479 | if (event & MEMAC_IEVNT_TS_ECC_ER) | |
480 | memac->exception_cb(memac->dev_id, FM_MAC_EX_TS_FIFO_ECC_ERR); | |
481 | if (event & MEMAC_IEVNT_TX_ECC_ER) | |
482 | memac->exception_cb(memac->dev_id, FM_MAC_EX_10G_TX_ECC_ER); | |
483 | if (event & MEMAC_IEVNT_RX_ECC_ER) | |
484 | memac->exception_cb(memac->dev_id, FM_MAC_EX_10G_RX_ECC_ER); | |
485 | } | |
486 | ||
487 | static void memac_exception(void *handle) | |
488 | { | |
489 | struct fman_mac *memac = (struct fman_mac *)handle; | |
490 | struct memac_regs __iomem *regs = memac->regs; | |
491 | u32 event, imask; | |
492 | ||
493 | event = ioread32be(®s->ievent); | |
494 | imask = ioread32be(®s->imask); | |
495 | ||
496 | /* Imask include both error and notification/event bits. | |
497 | * Leaving only error bits enabled by imask. | |
498 | * The imask error bits are shifted by 16 bits offset from | |
499 | * their corresponding location in the ievent - hence the >> 16 | |
500 | */ | |
501 | event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); | |
502 | ||
503 | iowrite32be(event, ®s->ievent); | |
504 | ||
505 | if (event & MEMAC_IEVNT_MGI) | |
506 | memac->exception_cb(memac->dev_id, | |
507 | FM_MAC_EX_MAGIC_PACKET_INDICATION); | |
508 | } | |
509 | ||
510 | static void free_init_resources(struct fman_mac *memac) | |
511 | { | |
512 | fman_unregister_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, | |
513 | FMAN_INTR_TYPE_ERR); | |
514 | ||
515 | fman_unregister_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, | |
516 | FMAN_INTR_TYPE_NORMAL); | |
517 | ||
518 | /* release the driver's group hash table */ | |
519 | free_hash_table(memac->multicast_addr_hash); | |
520 | memac->multicast_addr_hash = NULL; | |
521 | ||
522 | /* release the driver's individual hash table */ | |
523 | free_hash_table(memac->unicast_addr_hash); | |
524 | memac->unicast_addr_hash = NULL; | |
525 | } | |
526 | ||
1257c962 | 527 | static int memac_enable(struct fman_mac *memac) |
57ba4c9b | 528 | { |
5d93cfcf | 529 | int ret; |
57ba4c9b | 530 | |
5d93cfcf SA |
531 | ret = phy_init(memac->serdes); |
532 | if (ret) { | |
533 | dev_err(memac->dev_id->dev, | |
534 | "could not initialize serdes: %pe\n", ERR_PTR(ret)); | |
535 | return ret; | |
536 | } | |
57ba4c9b | 537 | |
5d93cfcf SA |
538 | ret = phy_power_on(memac->serdes); |
539 | if (ret) { | |
540 | dev_err(memac->dev_id->dev, | |
541 | "could not power on serdes: %pe\n", ERR_PTR(ret)); | |
542 | phy_exit(memac->serdes); | |
543 | } | |
57ba4c9b | 544 | |
5d93cfcf | 545 | return ret; |
57ba4c9b IL |
546 | } |
547 | ||
901bdff2 | 548 | static void memac_disable(struct fman_mac *memac) |
57ba4c9b | 549 | { |
5d93cfcf SA |
550 | phy_power_off(memac->serdes); |
551 | phy_exit(memac->serdes); | |
57ba4c9b IL |
552 | } |
553 | ||
1257c962 | 554 | static int memac_set_promiscuous(struct fman_mac *memac, bool new_val) |
57ba4c9b IL |
555 | { |
556 | struct memac_regs __iomem *regs = memac->regs; | |
557 | u32 tmp; | |
558 | ||
57ba4c9b IL |
559 | tmp = ioread32be(®s->command_config); |
560 | if (new_val) | |
561 | tmp |= CMD_CFG_PROMIS_EN; | |
562 | else | |
563 | tmp &= ~CMD_CFG_PROMIS_EN; | |
564 | ||
565 | iowrite32be(tmp, ®s->command_config); | |
566 | ||
567 | return 0; | |
568 | } | |
569 | ||
1257c962 SA |
570 | static int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority, |
571 | u16 pause_time, u16 thresh_time) | |
57ba4c9b IL |
572 | { |
573 | struct memac_regs __iomem *regs = memac->regs; | |
574 | u32 tmp; | |
575 | ||
57ba4c9b IL |
576 | tmp = ioread32be(®s->tx_fifo_sections); |
577 | ||
578 | GET_TX_EMPTY_DEFAULT_VALUE(tmp); | |
579 | iowrite32be(tmp, ®s->tx_fifo_sections); | |
580 | ||
581 | tmp = ioread32be(®s->command_config); | |
582 | tmp &= ~CMD_CFG_PFC_MODE; | |
57ba4c9b IL |
583 | |
584 | iowrite32be(tmp, ®s->command_config); | |
585 | ||
586 | tmp = ioread32be(®s->pause_quanta[priority / 2]); | |
587 | if (priority % 2) | |
588 | tmp &= CLXY_PAUSE_QUANTA_CLX_PQNT; | |
589 | else | |
590 | tmp &= CLXY_PAUSE_QUANTA_CLY_PQNT; | |
591 | tmp |= ((u32)pause_time << (16 * (priority % 2))); | |
592 | iowrite32be(tmp, ®s->pause_quanta[priority / 2]); | |
593 | ||
594 | tmp = ioread32be(®s->pause_thresh[priority / 2]); | |
595 | if (priority % 2) | |
596 | tmp &= CLXY_PAUSE_THRESH_CLX_QTH; | |
597 | else | |
598 | tmp &= CLXY_PAUSE_THRESH_CLY_QTH; | |
599 | tmp |= ((u32)thresh_time << (16 * (priority % 2))); | |
600 | iowrite32be(tmp, ®s->pause_thresh[priority / 2]); | |
601 | ||
602 | return 0; | |
603 | } | |
604 | ||
1257c962 | 605 | static int memac_accept_rx_pause_frames(struct fman_mac *memac, bool en) |
57ba4c9b IL |
606 | { |
607 | struct memac_regs __iomem *regs = memac->regs; | |
608 | u32 tmp; | |
609 | ||
57ba4c9b IL |
610 | tmp = ioread32be(®s->command_config); |
611 | if (en) | |
612 | tmp &= ~CMD_CFG_PAUSE_IGNORE; | |
613 | else | |
614 | tmp |= CMD_CFG_PAUSE_IGNORE; | |
615 | ||
616 | iowrite32be(tmp, ®s->command_config); | |
617 | ||
618 | return 0; | |
619 | } | |
620 | ||
2141297d RKO |
621 | static unsigned long memac_get_caps(struct phylink_config *config, |
622 | phy_interface_t interface) | |
5d93cfcf SA |
623 | { |
624 | struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; | |
625 | unsigned long caps = config->mac_capabilities; | |
626 | ||
2141297d | 627 | if (phy_interface_mode_is_rgmii(interface) && |
5d93cfcf SA |
628 | memac->rgmii_no_half_duplex) |
629 | caps &= ~(MAC_10HD | MAC_100HD); | |
630 | ||
2141297d | 631 | return caps; |
5d93cfcf SA |
632 | } |
633 | ||
634 | /** | |
635 | * memac_if_mode() - Convert an interface mode into an IF_MODE config | |
636 | * @interface: A phy interface mode | |
637 | * | |
638 | * Return: A configuration word, suitable for programming into the lower bits | |
639 | * of %IF_MODE. | |
640 | */ | |
641 | static u32 memac_if_mode(phy_interface_t interface) | |
642 | { | |
643 | switch (interface) { | |
644 | case PHY_INTERFACE_MODE_MII: | |
645 | return IF_MODE_MII; | |
646 | case PHY_INTERFACE_MODE_RGMII: | |
647 | case PHY_INTERFACE_MODE_RGMII_ID: | |
648 | case PHY_INTERFACE_MODE_RGMII_RXID: | |
649 | case PHY_INTERFACE_MODE_RGMII_TXID: | |
650 | return IF_MODE_GMII | IF_MODE_RGMII; | |
651 | case PHY_INTERFACE_MODE_SGMII: | |
652 | case PHY_INTERFACE_MODE_1000BASEX: | |
653 | case PHY_INTERFACE_MODE_QSGMII: | |
654 | return IF_MODE_GMII; | |
655 | case PHY_INTERFACE_MODE_10GBASER: | |
656 | return IF_MODE_10G; | |
657 | default: | |
658 | WARN_ON_ONCE(1); | |
659 | return 0; | |
660 | } | |
661 | } | |
662 | ||
663 | static struct phylink_pcs *memac_select_pcs(struct phylink_config *config, | |
664 | phy_interface_t iface) | |
665 | { | |
666 | struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; | |
667 | ||
668 | switch (iface) { | |
669 | case PHY_INTERFACE_MODE_SGMII: | |
670 | case PHY_INTERFACE_MODE_1000BASEX: | |
671 | return memac->sgmii_pcs; | |
672 | case PHY_INTERFACE_MODE_QSGMII: | |
673 | return memac->qsgmii_pcs; | |
674 | case PHY_INTERFACE_MODE_10GBASER: | |
675 | return memac->xfi_pcs; | |
676 | default: | |
677 | return NULL; | |
678 | } | |
679 | } | |
680 | ||
681 | static int memac_prepare(struct phylink_config *config, unsigned int mode, | |
682 | phy_interface_t iface) | |
683 | { | |
684 | struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; | |
685 | ||
686 | switch (iface) { | |
687 | case PHY_INTERFACE_MODE_SGMII: | |
688 | case PHY_INTERFACE_MODE_1000BASEX: | |
689 | case PHY_INTERFACE_MODE_QSGMII: | |
690 | case PHY_INTERFACE_MODE_10GBASER: | |
691 | return phy_set_mode_ext(memac->serdes, PHY_MODE_ETHERNET, | |
692 | iface); | |
693 | default: | |
694 | return 0; | |
695 | } | |
696 | } | |
697 | ||
698 | static void memac_mac_config(struct phylink_config *config, unsigned int mode, | |
699 | const struct phylink_link_state *state) | |
700 | { | |
701 | struct mac_device *mac_dev = fman_config_to_mac(config); | |
702 | struct memac_regs __iomem *regs = mac_dev->fman_mac->regs; | |
703 | u32 tmp = ioread32be(®s->if_mode); | |
704 | ||
705 | tmp &= ~(IF_MODE_MASK | IF_MODE_RGMII); | |
706 | tmp |= memac_if_mode(state->interface); | |
707 | if (phylink_autoneg_inband(mode)) | |
708 | tmp |= IF_MODE_RGMII_AUTO; | |
709 | iowrite32be(tmp, ®s->if_mode); | |
710 | } | |
711 | ||
712 | static void memac_link_up(struct phylink_config *config, struct phy_device *phy, | |
713 | unsigned int mode, phy_interface_t interface, | |
714 | int speed, int duplex, bool tx_pause, bool rx_pause) | |
715 | { | |
716 | struct mac_device *mac_dev = fman_config_to_mac(config); | |
717 | struct fman_mac *memac = mac_dev->fman_mac; | |
718 | struct memac_regs __iomem *regs = memac->regs; | |
719 | u32 tmp = memac_if_mode(interface); | |
720 | u16 pause_time = tx_pause ? FSL_FM_PAUSE_TIME_ENABLE : | |
721 | FSL_FM_PAUSE_TIME_DISABLE; | |
722 | ||
723 | memac_set_tx_pause_frames(memac, 0, pause_time, 0); | |
724 | memac_accept_rx_pause_frames(memac, rx_pause); | |
725 | ||
726 | if (duplex == DUPLEX_HALF) | |
727 | tmp |= IF_MODE_HD; | |
728 | ||
729 | switch (speed) { | |
730 | case SPEED_1000: | |
731 | tmp |= IF_MODE_RGMII_1000; | |
732 | break; | |
733 | case SPEED_100: | |
734 | tmp |= IF_MODE_RGMII_100; | |
735 | break; | |
736 | case SPEED_10: | |
737 | tmp |= IF_MODE_RGMII_10; | |
738 | break; | |
739 | } | |
740 | iowrite32be(tmp, ®s->if_mode); | |
741 | ||
742 | /* TODO: EEE? */ | |
743 | ||
744 | if (speed == SPEED_10000) { | |
745 | if (memac->fm_rev_info.major == 6 && | |
746 | memac->fm_rev_info.minor == 4) | |
747 | tmp = TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G; | |
748 | else | |
749 | tmp = TX_FIFO_SECTIONS_TX_AVAIL_10G; | |
750 | tmp |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G; | |
751 | } else { | |
752 | tmp = TX_FIFO_SECTIONS_TX_AVAIL_1G | | |
753 | TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G; | |
754 | } | |
755 | iowrite32be(tmp, ®s->tx_fifo_sections); | |
756 | ||
757 | mac_dev->update_speed(mac_dev, speed); | |
758 | ||
759 | tmp = ioread32be(®s->command_config); | |
760 | tmp |= CMD_CFG_RX_EN | CMD_CFG_TX_EN; | |
761 | iowrite32be(tmp, ®s->command_config); | |
762 | } | |
763 | ||
764 | static void memac_link_down(struct phylink_config *config, unsigned int mode, | |
765 | phy_interface_t interface) | |
766 | { | |
767 | struct fman_mac *memac = fman_config_to_mac(config)->fman_mac; | |
768 | struct memac_regs __iomem *regs = memac->regs; | |
769 | u32 tmp; | |
770 | ||
771 | /* TODO: graceful */ | |
772 | tmp = ioread32be(®s->command_config); | |
773 | tmp &= ~(CMD_CFG_RX_EN | CMD_CFG_TX_EN); | |
774 | iowrite32be(tmp, ®s->command_config); | |
775 | } | |
776 | ||
777 | static const struct phylink_mac_ops memac_mac_ops = { | |
2141297d | 778 | .mac_get_caps = memac_get_caps, |
5d93cfcf SA |
779 | .mac_select_pcs = memac_select_pcs, |
780 | .mac_prepare = memac_prepare, | |
781 | .mac_config = memac_mac_config, | |
782 | .mac_link_up = memac_link_up, | |
783 | .mac_link_down = memac_link_down, | |
784 | }; | |
785 | ||
1257c962 SA |
786 | static int memac_modify_mac_address(struct fman_mac *memac, |
787 | const enet_addr_t *enet_addr) | |
57ba4c9b | 788 | { |
76660757 | 789 | add_addr_in_paddr(memac->regs, (const u8 *)(*enet_addr), 0); |
57ba4c9b IL |
790 | |
791 | return 0; | |
792 | } | |
793 | ||
1257c962 SA |
794 | static int memac_add_hash_mac_address(struct fman_mac *memac, |
795 | enet_addr_t *eth_addr) | |
57ba4c9b IL |
796 | { |
797 | struct memac_regs __iomem *regs = memac->regs; | |
798 | struct eth_hash_entry *hash_entry; | |
799 | u32 hash; | |
800 | u64 addr; | |
801 | ||
57ba4c9b IL |
802 | addr = ENET_ADDR_TO_UINT64(*eth_addr); |
803 | ||
804 | if (!(addr & GROUP_ADDRESS)) { | |
805 | /* Unicast addresses not supported in hash */ | |
806 | pr_err("Unicast Address\n"); | |
807 | return -EINVAL; | |
808 | } | |
809 | hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK; | |
810 | ||
811 | /* Create element to be added to the driver hash table */ | |
0d9c9a23 | 812 | hash_entry = kmalloc(sizeof(*hash_entry), GFP_ATOMIC); |
57ba4c9b IL |
813 | if (!hash_entry) |
814 | return -ENOMEM; | |
815 | hash_entry->addr = addr; | |
816 | INIT_LIST_HEAD(&hash_entry->node); | |
817 | ||
818 | list_add_tail(&hash_entry->node, | |
819 | &memac->multicast_addr_hash->lsts[hash]); | |
820 | iowrite32be(hash | HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); | |
821 | ||
822 | return 0; | |
823 | } | |
824 | ||
1257c962 | 825 | static int memac_set_allmulti(struct fman_mac *memac, bool enable) |
c893238e RB |
826 | { |
827 | u32 entry; | |
828 | struct memac_regs __iomem *regs = memac->regs; | |
829 | ||
c893238e RB |
830 | if (enable) { |
831 | for (entry = 0; entry < HASH_TABLE_SIZE; entry++) | |
832 | iowrite32be(entry | HASH_CTRL_MCAST_EN, | |
833 | ®s->hashtable_ctrl); | |
834 | } else { | |
835 | for (entry = 0; entry < HASH_TABLE_SIZE; entry++) | |
836 | iowrite32be(entry & ~HASH_CTRL_MCAST_EN, | |
837 | ®s->hashtable_ctrl); | |
838 | } | |
839 | ||
840 | memac->allmulti_enabled = enable; | |
841 | ||
842 | return 0; | |
843 | } | |
844 | ||
1257c962 | 845 | static int memac_set_tstamp(struct fman_mac *memac, bool enable) |
0fab782a YL |
846 | { |
847 | return 0; /* Always enabled. */ | |
848 | } | |
849 | ||
1257c962 SA |
850 | static int memac_del_hash_mac_address(struct fman_mac *memac, |
851 | enet_addr_t *eth_addr) | |
57ba4c9b IL |
852 | { |
853 | struct memac_regs __iomem *regs = memac->regs; | |
854 | struct eth_hash_entry *hash_entry = NULL; | |
855 | struct list_head *pos; | |
856 | u32 hash; | |
857 | u64 addr; | |
858 | ||
57ba4c9b IL |
859 | addr = ENET_ADDR_TO_UINT64(*eth_addr); |
860 | ||
861 | hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK; | |
862 | ||
863 | list_for_each(pos, &memac->multicast_addr_hash->lsts[hash]) { | |
864 | hash_entry = ETH_HASH_ENTRY_OBJ(pos); | |
cc5d229a | 865 | if (hash_entry && hash_entry->addr == addr) { |
57ba4c9b IL |
866 | list_del_init(&hash_entry->node); |
867 | kfree(hash_entry); | |
868 | break; | |
869 | } | |
870 | } | |
c893238e RB |
871 | |
872 | if (!memac->allmulti_enabled) { | |
873 | if (list_empty(&memac->multicast_addr_hash->lsts[hash])) | |
874 | iowrite32be(hash & ~HASH_CTRL_MCAST_EN, | |
875 | ®s->hashtable_ctrl); | |
876 | } | |
57ba4c9b IL |
877 | |
878 | return 0; | |
879 | } | |
880 | ||
1257c962 SA |
881 | static int memac_set_exception(struct fman_mac *memac, |
882 | enum fman_mac_exceptions exception, bool enable) | |
57ba4c9b IL |
883 | { |
884 | u32 bit_mask = 0; | |
885 | ||
57ba4c9b IL |
886 | bit_mask = get_exception_flag(exception); |
887 | if (bit_mask) { | |
888 | if (enable) | |
889 | memac->exceptions |= bit_mask; | |
890 | else | |
891 | memac->exceptions &= ~bit_mask; | |
892 | } else { | |
893 | pr_err("Undefined exception\n"); | |
894 | return -EINVAL; | |
895 | } | |
896 | set_exception(memac->regs, bit_mask, enable); | |
897 | ||
898 | return 0; | |
899 | } | |
900 | ||
1257c962 | 901 | static int memac_init(struct fman_mac *memac) |
57ba4c9b IL |
902 | { |
903 | struct memac_cfg *memac_drv_param; | |
57ba4c9b | 904 | enet_addr_t eth_addr; |
57ba4c9b IL |
905 | int err; |
906 | u32 reg32 = 0; | |
907 | ||
57ba4c9b IL |
908 | err = check_init_parameters(memac); |
909 | if (err) | |
910 | return err; | |
911 | ||
912 | memac_drv_param = memac->memac_drv_param; | |
913 | ||
57ba4c9b IL |
914 | /* First, reset the MAC if desired. */ |
915 | if (memac_drv_param->reset_on_init) { | |
916 | err = reset(memac->regs); | |
917 | if (err) { | |
918 | pr_err("mEMAC reset failed\n"); | |
919 | return err; | |
920 | } | |
921 | } | |
922 | ||
923 | /* MAC Address */ | |
f3353b99 MB |
924 | if (memac->addr != 0) { |
925 | MAKE_ENET_ADDR_FROM_UINT64(memac->addr, eth_addr); | |
76660757 | 926 | add_addr_in_paddr(memac->regs, (const u8 *)eth_addr, 0); |
f3353b99 | 927 | } |
57ba4c9b | 928 | |
5d93cfcf | 929 | init(memac->regs, memac->memac_drv_param, memac->exceptions); |
57ba4c9b IL |
930 | |
931 | /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 errata workaround | |
932 | * Exists only in FMan 6.0 and 6.3. | |
933 | */ | |
934 | if ((memac->fm_rev_info.major == 6) && | |
935 | ((memac->fm_rev_info.minor == 0) || | |
936 | (memac->fm_rev_info.minor == 3))) { | |
937 | /* MAC strips CRC from received frames - this workaround | |
938 | * should decrease the likelihood of bug appearance | |
939 | */ | |
940 | reg32 = ioread32be(&memac->regs->command_config); | |
941 | reg32 &= ~CMD_CFG_CRC_FWD; | |
942 | iowrite32be(reg32, &memac->regs->command_config); | |
943 | } | |
944 | ||
57ba4c9b IL |
945 | /* Max Frame Length */ |
946 | err = fman_set_mac_max_frame(memac->fm, memac->mac_id, | |
947 | memac_drv_param->max_frame_length); | |
948 | if (err) { | |
949 | pr_err("settings Mac max frame length is FAILED\n"); | |
950 | return err; | |
951 | } | |
952 | ||
953 | memac->multicast_addr_hash = alloc_hash_table(HASH_TABLE_SIZE); | |
954 | if (!memac->multicast_addr_hash) { | |
955 | free_init_resources(memac); | |
956 | pr_err("allocation hash table is FAILED\n"); | |
957 | return -ENOMEM; | |
958 | } | |
959 | ||
960 | memac->unicast_addr_hash = alloc_hash_table(HASH_TABLE_SIZE); | |
961 | if (!memac->unicast_addr_hash) { | |
962 | free_init_resources(memac); | |
963 | pr_err("allocation hash table is FAILED\n"); | |
964 | return -ENOMEM; | |
965 | } | |
966 | ||
967 | fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, | |
968 | FMAN_INTR_TYPE_ERR, memac_err_exception, memac); | |
969 | ||
970 | fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, | |
971 | FMAN_INTR_TYPE_NORMAL, memac_exception, memac); | |
972 | ||
57ba4c9b IL |
973 | return 0; |
974 | } | |
975 | ||
a7c2a32e SA |
976 | static void pcs_put(struct phylink_pcs *pcs) |
977 | { | |
a7c2a32e SA |
978 | if (IS_ERR_OR_NULL(pcs)) |
979 | return; | |
980 | ||
a7c2a32e | 981 | lynx_pcs_destroy(pcs); |
a7c2a32e SA |
982 | } |
983 | ||
1257c962 | 984 | static int memac_free(struct fman_mac *memac) |
57ba4c9b IL |
985 | { |
986 | free_init_resources(memac); | |
987 | ||
a7c2a32e SA |
988 | pcs_put(memac->sgmii_pcs); |
989 | pcs_put(memac->qsgmii_pcs); | |
990 | pcs_put(memac->xfi_pcs); | |
57ba4c9b IL |
991 | kfree(memac->memac_drv_param); |
992 | kfree(memac); | |
993 | ||
994 | return 0; | |
995 | } | |
996 | ||
19c788b1 SA |
997 | static struct fman_mac *memac_config(struct mac_device *mac_dev, |
998 | struct fman_mac_params *params) | |
57ba4c9b IL |
999 | { |
1000 | struct fman_mac *memac; | |
1001 | struct memac_cfg *memac_drv_param; | |
57ba4c9b | 1002 | |
57ba4c9b IL |
1003 | /* allocate memory for the m_emac data structure */ |
1004 | memac = kzalloc(sizeof(*memac), GFP_KERNEL); | |
1005 | if (!memac) | |
1006 | return NULL; | |
1007 | ||
1008 | /* allocate memory for the m_emac driver parameters data structure */ | |
1009 | memac_drv_param = kzalloc(sizeof(*memac_drv_param), GFP_KERNEL); | |
1010 | if (!memac_drv_param) { | |
1011 | memac_free(memac); | |
1012 | return NULL; | |
1013 | } | |
1014 | ||
1015 | /* Plant parameter structure pointer */ | |
1016 | memac->memac_drv_param = memac_drv_param; | |
1017 | ||
1018 | set_dflts(memac_drv_param); | |
1019 | ||
19c788b1 | 1020 | memac->addr = ENET_ADDR_TO_UINT64(mac_dev->addr); |
57ba4c9b | 1021 | |
19c788b1 | 1022 | memac->regs = mac_dev->vaddr; |
57ba4c9b IL |
1023 | memac->mac_id = params->mac_id; |
1024 | memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | | |
1025 | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI); | |
1026 | memac->exception_cb = params->exception_cb; | |
1027 | memac->event_cb = params->event_cb; | |
19c788b1 | 1028 | memac->dev_id = mac_dev; |
57ba4c9b | 1029 | memac->fm = params->fm; |
57ba4c9b IL |
1030 | |
1031 | /* Save FMan revision */ | |
1032 | fman_get_revision(memac->fm, &memac->fm_rev_info); | |
1033 | ||
57ba4c9b IL |
1034 | return memac; |
1035 | } | |
302376fe | 1036 | |
a7c2a32e SA |
1037 | static struct phylink_pcs *memac_pcs_create(struct device_node *mac_node, |
1038 | int index) | |
1039 | { | |
1040 | struct device_node *node; | |
a7c2a32e SA |
1041 | struct phylink_pcs *pcs; |
1042 | ||
1043 | node = of_parse_phandle(mac_node, "pcsphy-handle", index); | |
32fc3035 | 1044 | if (!node) |
929a629c | 1045 | return ERR_PTR(-ENODEV); |
a7c2a32e | 1046 | |
929a629c RKO |
1047 | pcs = lynx_pcs_create_fwnode(of_fwnode_handle(node)); |
1048 | of_node_put(node); | |
efec2e2a | 1049 | |
a7c2a32e SA |
1050 | return pcs; |
1051 | } | |
1052 | ||
5d93cfcf SA |
1053 | static bool memac_supports(struct mac_device *mac_dev, phy_interface_t iface) |
1054 | { | |
1055 | /* If there's no serdes device, assume that it's been configured for | |
1056 | * whatever the default interface mode is. | |
1057 | */ | |
1058 | if (!mac_dev->fman_mac->serdes) | |
1059 | return mac_dev->phy_if == iface; | |
1060 | /* Otherwise, ask the serdes */ | |
1061 | return !phy_validate(mac_dev->fman_mac->serdes, PHY_MODE_ETHERNET, | |
1062 | iface, NULL); | |
1063 | } | |
1064 | ||
302376fe | 1065 | int memac_initialization(struct mac_device *mac_dev, |
c6b7b1b5 SA |
1066 | struct device_node *mac_node, |
1067 | struct fman_mac_params *params) | |
302376fe SA |
1068 | { |
1069 | int err; | |
5d93cfcf | 1070 | struct device_node *fixed; |
a7c2a32e | 1071 | struct phylink_pcs *pcs; |
44988627 | 1072 | struct fman_mac *memac; |
5d93cfcf SA |
1073 | unsigned long capabilities; |
1074 | unsigned long *supported; | |
302376fe | 1075 | |
734f06db VO |
1076 | /* The internal connection to the serdes is XGMII, but this isn't |
1077 | * really correct for the phy mode (which is the external connection). | |
1078 | * However, this is how all older device trees say that they want | |
1079 | * 10GBASE-R (aka XFI), so just convert it for them. | |
1080 | */ | |
1081 | if (mac_dev->phy_if == PHY_INTERFACE_MODE_XGMII) | |
1082 | mac_dev->phy_if = PHY_INTERFACE_MODE_10GBASER; | |
1083 | ||
5d93cfcf | 1084 | mac_dev->phylink_ops = &memac_mac_ops; |
302376fe SA |
1085 | mac_dev->set_promisc = memac_set_promiscuous; |
1086 | mac_dev->change_addr = memac_modify_mac_address; | |
1087 | mac_dev->add_hash_mac_addr = memac_add_hash_mac_address; | |
1088 | mac_dev->remove_hash_mac_addr = memac_del_hash_mac_address; | |
302376fe SA |
1089 | mac_dev->set_exception = memac_set_exception; |
1090 | mac_dev->set_allmulti = memac_set_allmulti; | |
1091 | mac_dev->set_tstamp = memac_set_tstamp; | |
1092 | mac_dev->set_multi = fman_set_multi; | |
302376fe SA |
1093 | mac_dev->enable = memac_enable; |
1094 | mac_dev->disable = memac_disable; | |
1095 | ||
19c788b1 | 1096 | mac_dev->fman_mac = memac_config(mac_dev, params); |
5d93cfcf SA |
1097 | if (!mac_dev->fman_mac) |
1098 | return -EINVAL; | |
302376fe | 1099 | |
44988627 SA |
1100 | memac = mac_dev->fman_mac; |
1101 | memac->memac_drv_param->max_frame_length = fman_get_max_frm(); | |
1102 | memac->memac_drv_param->reset_on_init = true; | |
a7c2a32e SA |
1103 | |
1104 | err = of_property_match_string(mac_node, "pcs-handle-names", "xfi"); | |
1105 | if (err >= 0) { | |
1106 | memac->xfi_pcs = memac_pcs_create(mac_node, err); | |
1107 | if (IS_ERR(memac->xfi_pcs)) { | |
1108 | err = PTR_ERR(memac->xfi_pcs); | |
1109 | dev_err_probe(mac_dev->dev, err, "missing xfi pcs\n"); | |
45fa34bf SA |
1110 | goto _return_fm_mac_free; |
1111 | } | |
a7c2a32e SA |
1112 | } else if (err != -EINVAL && err != -ENODATA) { |
1113 | goto _return_fm_mac_free; | |
1114 | } | |
45fa34bf | 1115 | |
a7c2a32e SA |
1116 | err = of_property_match_string(mac_node, "pcs-handle-names", "qsgmii"); |
1117 | if (err >= 0) { | |
1118 | memac->qsgmii_pcs = memac_pcs_create(mac_node, err); | |
1119 | if (IS_ERR(memac->qsgmii_pcs)) { | |
1120 | err = PTR_ERR(memac->qsgmii_pcs); | |
1121 | dev_err_probe(mac_dev->dev, err, | |
1122 | "missing qsgmii pcs\n"); | |
45fa34bf SA |
1123 | goto _return_fm_mac_free; |
1124 | } | |
a7c2a32e SA |
1125 | } else if (err != -EINVAL && err != -ENODATA) { |
1126 | goto _return_fm_mac_free; | |
1127 | } | |
1128 | ||
1129 | /* For compatibility, if pcs-handle-names is missing, we assume this | |
1130 | * phy is the first one in pcsphy-handle | |
1131 | */ | |
1132 | err = of_property_match_string(mac_node, "pcs-handle-names", "sgmii"); | |
1133 | if (err == -EINVAL || err == -ENODATA) | |
1134 | pcs = memac_pcs_create(mac_node, 0); | |
1135 | else if (err < 0) | |
1136 | goto _return_fm_mac_free; | |
1137 | else | |
1138 | pcs = memac_pcs_create(mac_node, err); | |
1139 | ||
5d93cfcf SA |
1140 | if (IS_ERR(pcs)) { |
1141 | err = PTR_ERR(pcs); | |
1142 | dev_err_probe(mac_dev->dev, err, "missing pcs\n"); | |
a7c2a32e | 1143 | goto _return_fm_mac_free; |
45fa34bf | 1144 | } |
302376fe | 1145 | |
a7c2a32e SA |
1146 | /* If err is set here, it means that pcs-handle-names was missing above |
1147 | * (and therefore that xfi_pcs cannot be set). If we are defaulting to | |
1148 | * XGMII, assume this is for XFI. Otherwise, assume it is for SGMII. | |
1149 | */ | |
734f06db | 1150 | if (err && mac_dev->phy_if == PHY_INTERFACE_MODE_10GBASER) |
a7c2a32e SA |
1151 | memac->xfi_pcs = pcs; |
1152 | else | |
1153 | memac->sgmii_pcs = pcs; | |
1154 | ||
a6ebcae7 GU |
1155 | memac->serdes = devm_of_phy_optional_get(mac_dev->dev, mac_node, |
1156 | "serdes"); | |
1157 | if (!memac->serdes) { | |
0fc83bd7 | 1158 | dev_dbg(mac_dev->dev, "could not get (optional) serdes\n"); |
0fc83bd7 | 1159 | } else if (IS_ERR(memac->serdes)) { |
a6ebcae7 | 1160 | err = PTR_ERR(memac->serdes); |
0fc83bd7 | 1161 | goto _return_fm_mac_free; |
5d93cfcf | 1162 | } |
0fc83bd7 | 1163 | |
5d93cfcf SA |
1164 | /* TODO: The following interface modes are supported by (some) hardware |
1165 | * but not by this driver: | |
1166 | * - 1000BASE-KX | |
1167 | * - 10GBASE-KR | |
1168 | * - XAUI/HiGig | |
1169 | */ | |
1170 | supported = mac_dev->phylink_config.supported_interfaces; | |
0fc83bd7 | 1171 | |
5d93cfcf SA |
1172 | /* Note that half duplex is only supported on 10/100M interfaces. */ |
1173 | ||
1174 | if (memac->sgmii_pcs && | |
1175 | (memac_supports(mac_dev, PHY_INTERFACE_MODE_SGMII) || | |
1176 | memac_supports(mac_dev, PHY_INTERFACE_MODE_1000BASEX))) { | |
1177 | __set_bit(PHY_INTERFACE_MODE_SGMII, supported); | |
1178 | __set_bit(PHY_INTERFACE_MODE_1000BASEX, supported); | |
0fc83bd7 SA |
1179 | } |
1180 | ||
5d93cfcf SA |
1181 | if (memac->sgmii_pcs && |
1182 | memac_supports(mac_dev, PHY_INTERFACE_MODE_2500BASEX)) | |
1183 | __set_bit(PHY_INTERFACE_MODE_2500BASEX, supported); | |
302376fe | 1184 | |
5d93cfcf SA |
1185 | if (memac->qsgmii_pcs && |
1186 | memac_supports(mac_dev, PHY_INTERFACE_MODE_QSGMII)) | |
1187 | __set_bit(PHY_INTERFACE_MODE_QSGMII, supported); | |
1188 | else if (mac_dev->phy_if == PHY_INTERFACE_MODE_QSGMII) | |
1189 | dev_warn(mac_dev->dev, "no QSGMII pcs specified\n"); | |
302376fe | 1190 | |
5d93cfcf SA |
1191 | if (memac->xfi_pcs && |
1192 | memac_supports(mac_dev, PHY_INTERFACE_MODE_10GBASER)) { | |
1193 | __set_bit(PHY_INTERFACE_MODE_10GBASER, supported); | |
1194 | } else { | |
1195 | /* From what I can tell, no 10g macs support RGMII. */ | |
1196 | phy_interface_set_rgmii(supported); | |
1197 | __set_bit(PHY_INTERFACE_MODE_MII, supported); | |
1198 | } | |
302376fe | 1199 | |
5d93cfcf SA |
1200 | capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE | MAC_10 | MAC_100; |
1201 | capabilities |= MAC_1000FD | MAC_2500FD | MAC_10000FD; | |
302376fe | 1202 | |
5d93cfcf SA |
1203 | /* These SoCs don't support half duplex at all; there's no different |
1204 | * FMan version or compatible, so we just have to check the machine | |
1205 | * compatible instead | |
1206 | */ | |
1207 | if (of_machine_is_compatible("fsl,ls1043a") || | |
1208 | of_machine_is_compatible("fsl,ls1046a") || | |
1209 | of_machine_is_compatible("fsl,B4QDS")) | |
1210 | capabilities &= ~(MAC_10HD | MAC_100HD); | |
302376fe | 1211 | |
5d93cfcf SA |
1212 | mac_dev->phylink_config.mac_capabilities = capabilities; |
1213 | ||
1214 | /* The T2080 and T4240 don't support half duplex RGMII. There is no | |
1215 | * other way to identify these SoCs, so just use the machine | |
1216 | * compatible. | |
1217 | */ | |
1218 | if (of_machine_is_compatible("fsl,T2080QDS") || | |
1219 | of_machine_is_compatible("fsl,T2080RDB") || | |
1220 | of_machine_is_compatible("fsl,T2081QDS") || | |
1221 | of_machine_is_compatible("fsl,T4240QDS") || | |
1222 | of_machine_is_compatible("fsl,T4240RDB")) | |
1223 | memac->rgmii_no_half_duplex = true; | |
1224 | ||
1225 | /* Most boards should use MLO_AN_INBAND, but existing boards don't have | |
1226 | * a managed property. Default to MLO_AN_INBAND if nothing else is | |
1227 | * specified. We need to be careful and not enable this if we have a | |
1228 | * fixed link or if we are using MII or RGMII, since those | |
1229 | * configurations modes don't use in-band autonegotiation. | |
1230 | */ | |
1231 | fixed = of_get_child_by_name(mac_node, "fixed-link"); | |
1232 | if (!fixed && !of_property_read_bool(mac_node, "fixed-link") && | |
1233 | !of_property_read_bool(mac_node, "managed") && | |
1234 | mac_dev->phy_if != PHY_INTERFACE_MODE_MII && | |
1235 | !phy_interface_mode_is_rgmii(mac_dev->phy_if)) | |
1236 | mac_dev->phylink_config.ovr_an_inband = true; | |
1237 | of_node_put(fixed); | |
302376fe SA |
1238 | |
1239 | err = memac_init(mac_dev->fman_mac); | |
1240 | if (err < 0) | |
5d93cfcf | 1241 | goto _return_fm_mac_free; |
302376fe SA |
1242 | |
1243 | dev_info(mac_dev->dev, "FMan MEMAC\n"); | |
1244 | ||
5d93cfcf | 1245 | return 0; |
302376fe | 1246 | |
302376fe SA |
1247 | _return_fm_mac_free: |
1248 | memac_free(mac_dev->fman_mac); | |
302376fe SA |
1249 | return err; |
1250 | } |