1 | #include <machine/rtems-bsd-kernel-space.h> |
---|
2 | |
---|
3 | #include <rtems/bsd/local/opt_dpaa.h> |
---|
4 | |
---|
5 | /* |
---|
6 | * Copyright 2008-2015 Freescale Semiconductor Inc. |
---|
7 | * |
---|
8 | * Redistribution and use in source and binary forms, with or without |
---|
9 | * modification, are permitted provided that the following conditions are met: |
---|
10 | * * Redistributions of source code must retain the above copyright |
---|
11 | * notice, this list of conditions and the following disclaimer. |
---|
12 | * * Redistributions in binary form must reproduce the above copyright |
---|
13 | * notice, this list of conditions and the following disclaimer in the |
---|
14 | * documentation and/or other materials provided with the distribution. |
---|
15 | * * Neither the name of Freescale Semiconductor nor the |
---|
16 | * names of its contributors may be used to endorse or promote products |
---|
17 | * derived from this software without specific prior written permission. |
---|
18 | * |
---|
19 | * |
---|
20 | * ALTERNATIVELY, this software may be distributed under the terms of the |
---|
21 | * GNU General Public License ("GPL") as published by the Free Software |
---|
22 | * Foundation, either version 2 of that License or (at your option) any |
---|
23 | * later version. |
---|
24 | * |
---|
25 | * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY |
---|
26 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
---|
27 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
---|
28 | * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY |
---|
29 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
---|
30 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
---|
31 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
---|
32 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
---|
33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
---|
34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
35 | */ |
---|
36 | |
---|
37 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
38 | |
---|
39 | #include "fman_memac.h" |
---|
40 | #include "fman.h" |
---|
41 | |
---|
42 | #include <linux/slab.h> |
---|
43 | #include <linux/io.h> |
---|
44 | #include <linux/phy.h> |
---|
45 | #include <linux/phy_fixed.h> |
---|
46 | #include <linux/of_mdio.h> |
---|
47 | |
---|
48 | /* PCS registers */ |
---|
49 | #define MDIO_SGMII_CR 0x00 |
---|
50 | #define MDIO_SGMII_DEV_ABIL_SGMII 0x04 |
---|
51 | #define MDIO_SGMII_LINK_TMR_L 0x12 |
---|
52 | #define MDIO_SGMII_LINK_TMR_H 0x13 |
---|
53 | #define MDIO_SGMII_IF_MODE 0x14 |
---|
54 | |
---|
55 | /* SGMII Control defines */ |
---|
56 | #define SGMII_CR_AN_EN 0x1000 |
---|
57 | #define SGMII_CR_RESTART_AN 0x0200 |
---|
58 | #define SGMII_CR_FD 0x0100 |
---|
59 | #define SGMII_CR_SPEED_SEL1_1G 0x0040 |
---|
60 | #define SGMII_CR_DEF_VAL (SGMII_CR_AN_EN | SGMII_CR_FD | \ |
---|
61 | SGMII_CR_SPEED_SEL1_1G) |
---|
62 | |
---|
63 | /* SGMII Device Ability for SGMII defines */ |
---|
64 | #define MDIO_SGMII_DEV_ABIL_SGMII_MODE 0x4001 |
---|
65 | #define MDIO_SGMII_DEV_ABIL_BASEX_MODE 0x01A0 |
---|
66 | |
---|
67 | /* Link timer define */ |
---|
68 | #define LINK_TMR_L 0xa120 |
---|
69 | #define LINK_TMR_H 0x0007 |
---|
70 | #define LINK_TMR_L_BASEX 0xaf08 |
---|
71 | #define LINK_TMR_H_BASEX 0x002f |
---|
72 | |
---|
73 | /* SGMII IF Mode defines */ |
---|
74 | #define IF_MODE_USE_SGMII_AN 0x0002 |
---|
75 | #define IF_MODE_SGMII_EN 0x0001 |
---|
76 | #define IF_MODE_SGMII_SPEED_100M 0x0004 |
---|
77 | #define IF_MODE_SGMII_SPEED_1G 0x0008 |
---|
78 | #define IF_MODE_SGMII_DUPLEX_HALF 0x0010 |
---|
79 | |
---|
80 | /* Num of additional exact match MAC adr regs */ |
---|
81 | #define MEMAC_NUM_OF_PADDRS 7 |
---|
82 | |
---|
83 | /* Control and Configuration Register (COMMAND_CONFIG) */ |
---|
84 | #define CMD_CFG_REG_LOWP_RXETY 0x01000000 /* 07 Rx low power indication */ |
---|
85 | #define CMD_CFG_TX_LOWP_ENA 0x00800000 /* 08 Tx Low Power Idle Enable */ |
---|
86 | #define CMD_CFG_PFC_MODE 0x00080000 /* 12 Enable PFC */ |
---|
87 | #define CMD_CFG_NO_LEN_CHK 0x00020000 /* 14 Payload length check disable */ |
---|
88 | #define CMD_CFG_SW_RESET 0x00001000 /* 19 S/W Reset, self clearing bit */ |
---|
89 | #define CMD_CFG_TX_PAD_EN 0x00000800 /* 20 Enable Tx padding of frames */ |
---|
90 | #define CMD_CFG_PAUSE_IGNORE 0x00000100 /* 23 Ignore Pause frame quanta */ |
---|
91 | #define CMD_CFG_CRC_FWD 0x00000040 /* 25 Terminate/frwd CRC of frames */ |
---|
92 | #define CMD_CFG_PAD_EN 0x00000020 /* 26 Frame padding removal */ |
---|
93 | #define CMD_CFG_PROMIS_EN 0x00000010 /* 27 Promiscuous operation enable */ |
---|
94 | #define CMD_CFG_RX_EN 0x00000002 /* 30 MAC receive path enable */ |
---|
95 | #define CMD_CFG_TX_EN 0x00000001 /* 31 MAC transmit path enable */ |
---|
96 | |
---|
97 | /* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */ |
---|
98 | #define TX_FIFO_SECTIONS_TX_EMPTY_MASK 0xFFFF0000 |
---|
99 | #define TX_FIFO_SECTIONS_TX_AVAIL_MASK 0x0000FFFF |
---|
100 | #define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G 0x00400000 |
---|
101 | #define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G 0x00100000 |
---|
102 | #define TX_FIFO_SECTIONS_TX_AVAIL_10G 0x00000019 |
---|
103 | #define TX_FIFO_SECTIONS_TX_AVAIL_1G 0x00000020 |
---|
104 | #define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G 0x00000060 |
---|
105 | |
---|
106 | #define GET_TX_EMPTY_DEFAULT_VALUE(_val) \ |
---|
107 | do { \ |
---|
108 | _val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK; \ |
---|
109 | ((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ? \ |
---|
110 | (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) :\ |
---|
111 | (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));\ |
---|
112 | } while (0) |
---|
113 | |
---|
114 | /* Interface Mode Register (IF_MODE) */ |
---|
115 | |
---|
116 | #define IF_MODE_MASK 0x00000003 /* 30-31 Mask on i/f mode bits */ |
---|
117 | #define IF_MODE_XGMII 0x00000000 /* 30-31 XGMII (10G) interface */ |
---|
118 | #define IF_MODE_GMII 0x00000002 /* 30-31 GMII (1G) interface */ |
---|
119 | #define IF_MODE_RGMII 0x00000004 |
---|
120 | #define IF_MODE_RGMII_AUTO 0x00008000 |
---|
121 | #define IF_MODE_RGMII_1000 0x00004000 /* 10 - 1000Mbps RGMII */ |
---|
122 | #define IF_MODE_RGMII_100 0x00000000 /* 00 - 100Mbps RGMII */ |
---|
123 | #define IF_MODE_RGMII_10 0x00002000 /* 01 - 10Mbps RGMII */ |
---|
124 | #define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */ |
---|
125 | #define IF_MODE_RGMII_FD 0x00001000 /* Full duplex RGMII */ |
---|
126 | #define IF_MODE_HD 0x00000040 /* Half duplex operation */ |
---|
127 | |
---|
128 | /* Hash table Control Register (HASHTABLE_CTRL) */ |
---|
129 | #define HASH_CTRL_MCAST_EN 0x00000100 |
---|
130 | /* 26-31 Hash table address code */ |
---|
131 | #define HASH_CTRL_ADDR_MASK 0x0000003F |
---|
132 | /* MAC mcast indication */ |
---|
133 | #define GROUP_ADDRESS 0x0000010000000000LL |
---|
134 | #define HASH_TABLE_SIZE 64 /* Hash tbl size */ |
---|
135 | |
---|
136 | /* Interrupt Mask Register (IMASK) */ |
---|
137 | #define MEMAC_IMASK_MGI 0x40000000 /* 1 Magic pkt detect indication */ |
---|
138 | #define MEMAC_IMASK_TSECC_ER 0x20000000 /* 2 Timestamp FIFO ECC error evnt */ |
---|
139 | #define MEMAC_IMASK_TECC_ER 0x02000000 /* 6 Transmit frame ECC error evnt */ |
---|
140 | #define MEMAC_IMASK_RECC_ER 0x01000000 /* 7 Receive frame ECC error evnt */ |
---|
141 | |
---|
142 | #define MEMAC_ALL_ERRS_IMASK \ |
---|
143 | ((u32)(MEMAC_IMASK_TSECC_ER | \ |
---|
144 | MEMAC_IMASK_TECC_ER | \ |
---|
145 | MEMAC_IMASK_RECC_ER | \ |
---|
146 | MEMAC_IMASK_MGI)) |
---|
147 | |
---|
148 | #define MEMAC_IEVNT_PCS 0x80000000 /* PCS (XG). Link sync (G) */ |
---|
149 | #define MEMAC_IEVNT_AN 0x40000000 /* Auto-negotiation */ |
---|
150 | #define MEMAC_IEVNT_LT 0x20000000 /* Link Training/New page */ |
---|
151 | #define MEMAC_IEVNT_MGI 0x00004000 /* Magic pkt detection */ |
---|
152 | #define MEMAC_IEVNT_TS_ECC_ER 0x00002000 /* Timestamp FIFO ECC error*/ |
---|
153 | #define MEMAC_IEVNT_RX_FIFO_OVFL 0x00001000 /* Rx FIFO overflow */ |
---|
154 | #define MEMAC_IEVNT_TX_FIFO_UNFL 0x00000800 /* Tx FIFO underflow */ |
---|
155 | #define MEMAC_IEVNT_TX_FIFO_OVFL 0x00000400 /* Tx FIFO overflow */ |
---|
156 | #define MEMAC_IEVNT_TX_ECC_ER 0x00000200 /* Tx frame ECC error */ |
---|
157 | #define MEMAC_IEVNT_RX_ECC_ER 0x00000100 /* Rx frame ECC error */ |
---|
158 | #define MEMAC_IEVNT_LI_FAULT 0x00000080 /* Link Interruption flt */ |
---|
159 | #define MEMAC_IEVNT_RX_EMPTY 0x00000040 /* Rx FIFO empty */ |
---|
160 | #define MEMAC_IEVNT_TX_EMPTY 0x00000020 /* Tx FIFO empty */ |
---|
161 | #define MEMAC_IEVNT_RX_LOWP 0x00000010 /* Low Power Idle */ |
---|
162 | #define MEMAC_IEVNT_PHY_LOS 0x00000004 /* Phy loss of signal */ |
---|
163 | #define MEMAC_IEVNT_REM_FAULT 0x00000002 /* Remote fault (XGMII) */ |
---|
164 | #define MEMAC_IEVNT_LOC_FAULT 0x00000001 /* Local fault (XGMII) */ |
---|
165 | |
---|
166 | #define DEFAULT_PAUSE_QUANTA 0xf000 |
---|
167 | #define DEFAULT_FRAME_LENGTH 0x600 |
---|
168 | #define DEFAULT_TX_IPG_LENGTH 12 |
---|
169 | |
---|
170 | #define CLXY_PAUSE_QUANTA_CLX_PQNT 0x0000FFFF |
---|
171 | #define CLXY_PAUSE_QUANTA_CLY_PQNT 0xFFFF0000 |
---|
172 | #define CLXY_PAUSE_THRESH_CLX_QTH 0x0000FFFF |
---|
173 | #define CLXY_PAUSE_THRESH_CLY_QTH 0xFFFF0000 |
---|
174 | |
---|
175 | struct mac_addr { |
---|
176 | /* Lower 32 bits of 48-bit MAC address */ |
---|
177 | u32 mac_addr_l; |
---|
178 | /* Upper 16 bits of 48-bit MAC address */ |
---|
179 | u32 mac_addr_u; |
---|
180 | }; |
---|
181 | |
---|
182 | /* memory map */ |
---|
183 | struct memac_regs { |
---|
184 | u32 res0000[2]; /* General Control and Status */ |
---|
185 | u32 command_config; /* 0x008 Ctrl and cfg */ |
---|
186 | struct mac_addr mac_addr0; /* 0x00C-0x010 MAC_ADDR_0...1 */ |
---|
187 | u32 maxfrm; /* 0x014 Max frame length */ |
---|
188 | u32 res0018[1]; |
---|
189 | u32 rx_fifo_sections; /* Receive FIFO configuration reg */ |
---|
190 | u32 tx_fifo_sections; /* Transmit FIFO configuration reg */ |
---|
191 | u32 res0024[2]; |
---|
192 | u32 hashtable_ctrl; /* 0x02C Hash table control */ |
---|
193 | u32 res0030[4]; |
---|
194 | u32 ievent; /* 0x040 Interrupt event */ |
---|
195 | u32 tx_ipg_length; /* 0x044 Transmitter inter-packet-gap */ |
---|
196 | u32 res0048; |
---|
197 | u32 imask; /* 0x04C Interrupt mask */ |
---|
198 | u32 res0050; |
---|
199 | u32 pause_quanta[4]; /* 0x054 Pause quanta */ |
---|
200 | u32 pause_thresh[4]; /* 0x064 Pause quanta threshold */ |
---|
201 | u32 rx_pause_status; /* 0x074 Receive pause status */ |
---|
202 | u32 res0078[2]; |
---|
203 | struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS];/* 0x80-0x0B4 mac padr */ |
---|
204 | u32 lpwake_timer; /* 0x0B8 Low Power Wakeup Timer */ |
---|
205 | u32 sleep_timer; /* 0x0BC Transmit EEE Low Power Timer */ |
---|
206 | u32 res00c0[8]; |
---|
207 | u32 statn_config; /* 0x0E0 Statistics configuration */ |
---|
208 | u32 res00e4[7]; |
---|
209 | /* Rx Statistics Counter */ |
---|
210 | u32 reoct_l; |
---|
211 | u32 reoct_u; |
---|
212 | u32 roct_l; |
---|
213 | u32 roct_u; |
---|
214 | u32 raln_l; |
---|
215 | u32 raln_u; |
---|
216 | u32 rxpf_l; |
---|
217 | u32 rxpf_u; |
---|
218 | u32 rfrm_l; |
---|
219 | u32 rfrm_u; |
---|
220 | u32 rfcs_l; |
---|
221 | u32 rfcs_u; |
---|
222 | u32 rvlan_l; |
---|
223 | u32 rvlan_u; |
---|
224 | u32 rerr_l; |
---|
225 | u32 rerr_u; |
---|
226 | u32 ruca_l; |
---|
227 | u32 ruca_u; |
---|
228 | u32 rmca_l; |
---|
229 | u32 rmca_u; |
---|
230 | u32 rbca_l; |
---|
231 | u32 rbca_u; |
---|
232 | u32 rdrp_l; |
---|
233 | u32 rdrp_u; |
---|
234 | u32 rpkt_l; |
---|
235 | u32 rpkt_u; |
---|
236 | u32 rund_l; |
---|
237 | u32 rund_u; |
---|
238 | u32 r64_l; |
---|
239 | u32 r64_u; |
---|
240 | u32 r127_l; |
---|
241 | u32 r127_u; |
---|
242 | u32 r255_l; |
---|
243 | u32 r255_u; |
---|
244 | u32 r511_l; |
---|
245 | u32 r511_u; |
---|
246 | u32 r1023_l; |
---|
247 | u32 r1023_u; |
---|
248 | u32 r1518_l; |
---|
249 | u32 r1518_u; |
---|
250 | u32 r1519x_l; |
---|
251 | u32 r1519x_u; |
---|
252 | u32 rovr_l; |
---|
253 | u32 rovr_u; |
---|
254 | u32 rjbr_l; |
---|
255 | u32 rjbr_u; |
---|
256 | u32 rfrg_l; |
---|
257 | u32 rfrg_u; |
---|
258 | u32 rcnp_l; |
---|
259 | u32 rcnp_u; |
---|
260 | u32 rdrntp_l; |
---|
261 | u32 rdrntp_u; |
---|
262 | u32 res01d0[12]; |
---|
263 | /* Tx Statistics Counter */ |
---|
264 | u32 teoct_l; |
---|
265 | u32 teoct_u; |
---|
266 | u32 toct_l; |
---|
267 | u32 toct_u; |
---|
268 | u32 res0210[2]; |
---|
269 | u32 txpf_l; |
---|
270 | u32 txpf_u; |
---|
271 | u32 tfrm_l; |
---|
272 | u32 tfrm_u; |
---|
273 | u32 tfcs_l; |
---|
274 | u32 tfcs_u; |
---|
275 | u32 tvlan_l; |
---|
276 | u32 tvlan_u; |
---|
277 | u32 terr_l; |
---|
278 | u32 terr_u; |
---|
279 | u32 tuca_l; |
---|
280 | u32 tuca_u; |
---|
281 | u32 tmca_l; |
---|
282 | u32 tmca_u; |
---|
283 | u32 tbca_l; |
---|
284 | u32 tbca_u; |
---|
285 | u32 res0258[2]; |
---|
286 | u32 tpkt_l; |
---|
287 | u32 tpkt_u; |
---|
288 | u32 tund_l; |
---|
289 | u32 tund_u; |
---|
290 | u32 t64_l; |
---|
291 | u32 t64_u; |
---|
292 | u32 t127_l; |
---|
293 | u32 t127_u; |
---|
294 | u32 t255_l; |
---|
295 | u32 t255_u; |
---|
296 | u32 t511_l; |
---|
297 | u32 t511_u; |
---|
298 | u32 t1023_l; |
---|
299 | u32 t1023_u; |
---|
300 | u32 t1518_l; |
---|
301 | u32 t1518_u; |
---|
302 | u32 t1519x_l; |
---|
303 | u32 t1519x_u; |
---|
304 | u32 res02a8[6]; |
---|
305 | u32 tcnp_l; |
---|
306 | u32 tcnp_u; |
---|
307 | u32 res02c8[14]; |
---|
308 | /* Line Interface Control */ |
---|
309 | u32 if_mode; /* 0x300 Interface Mode Control */ |
---|
310 | u32 if_status; /* 0x304 Interface Status */ |
---|
311 | u32 res0308[14]; |
---|
312 | /* HiGig/2 */ |
---|
313 | u32 hg_config; /* 0x340 Control and cfg */ |
---|
314 | u32 res0344[3]; |
---|
315 | u32 hg_pause_quanta; /* 0x350 Pause quanta */ |
---|
316 | u32 res0354[3]; |
---|
317 | u32 hg_pause_thresh; /* 0x360 Pause quanta threshold */ |
---|
318 | u32 res0364[3]; |
---|
319 | u32 hgrx_pause_status; /* 0x370 Receive pause status */ |
---|
320 | u32 hg_fifos_status; /* 0x374 fifos status */ |
---|
321 | u32 rhm; /* 0x378 rx messages counter */ |
---|
322 | u32 thm; /* 0x37C tx messages counter */ |
---|
323 | }; |
---|
324 | |
---|
325 | struct memac_cfg { |
---|
326 | bool reset_on_init; |
---|
327 | bool pause_ignore; |
---|
328 | bool promiscuous_mode_enable; |
---|
329 | struct fixed_phy_status *fixed_link; |
---|
330 | u16 max_frame_length; |
---|
331 | u16 pause_quanta; |
---|
332 | u32 tx_ipg_length; |
---|
333 | }; |
---|
334 | |
---|
335 | struct fman_mac { |
---|
336 | /* Pointer to MAC memory mapped registers */ |
---|
337 | struct memac_regs __iomem *regs; |
---|
338 | /* MAC address of device */ |
---|
339 | u64 addr; |
---|
340 | /* Ethernet physical interface */ |
---|
341 | phy_interface_t phy_if; |
---|
342 | u16 max_speed; |
---|
343 | void *dev_id; /* device cookie used by the exception cbs */ |
---|
344 | fman_mac_exception_cb *exception_cb; |
---|
345 | fman_mac_exception_cb *event_cb; |
---|
346 | /* Pointer to driver's global address hash table */ |
---|
347 | struct eth_hash_t *multicast_addr_hash; |
---|
348 | /* Pointer to driver's individual address hash table */ |
---|
349 | struct eth_hash_t *unicast_addr_hash; |
---|
350 | u8 mac_id; |
---|
351 | u32 exceptions; |
---|
352 | struct memac_cfg *memac_drv_param; |
---|
353 | void *fm; |
---|
354 | struct fman_rev_info fm_rev_info; |
---|
355 | bool basex_if; |
---|
356 | struct phy_device *pcsphy; |
---|
357 | }; |
---|
358 | |
---|
359 | static void add_addr_in_paddr(struct memac_regs __iomem *regs, u8 *adr, |
---|
360 | u8 paddr_num) |
---|
361 | { |
---|
362 | u32 tmp0, tmp1; |
---|
363 | |
---|
364 | tmp0 = (u32)(adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24); |
---|
365 | tmp1 = (u32)(adr[4] | adr[5] << 8); |
---|
366 | |
---|
367 | if (paddr_num == 0) { |
---|
368 | iowrite32be(tmp0, ®s->mac_addr0.mac_addr_l); |
---|
369 | iowrite32be(tmp1, ®s->mac_addr0.mac_addr_u); |
---|
370 | } else { |
---|
371 | iowrite32be(tmp0, ®s->mac_addr[paddr_num - 1].mac_addr_l); |
---|
372 | iowrite32be(tmp1, ®s->mac_addr[paddr_num - 1].mac_addr_u); |
---|
373 | } |
---|
374 | } |
---|
375 | |
---|
376 | static int reset(struct memac_regs __iomem *regs) |
---|
377 | { |
---|
378 | u32 tmp; |
---|
379 | int count; |
---|
380 | |
---|
381 | tmp = ioread32be(®s->command_config); |
---|
382 | |
---|
383 | tmp |= CMD_CFG_SW_RESET; |
---|
384 | |
---|
385 | iowrite32be(tmp, ®s->command_config); |
---|
386 | |
---|
387 | count = 100; |
---|
388 | do { |
---|
389 | udelay(1); |
---|
390 | } while ((ioread32be(®s->command_config) & CMD_CFG_SW_RESET) && |
---|
391 | --count); |
---|
392 | |
---|
393 | if (count == 0) |
---|
394 | return -EBUSY; |
---|
395 | |
---|
396 | return 0; |
---|
397 | } |
---|
398 | |
---|
399 | static void set_exception(struct memac_regs __iomem *regs, u32 val, |
---|
400 | bool enable) |
---|
401 | { |
---|
402 | u32 tmp; |
---|
403 | |
---|
404 | tmp = ioread32be(®s->imask); |
---|
405 | if (enable) |
---|
406 | tmp |= val; |
---|
407 | else |
---|
408 | tmp &= ~val; |
---|
409 | |
---|
410 | iowrite32be(tmp, ®s->imask); |
---|
411 | } |
---|
412 | |
---|
413 | static int init(struct memac_regs __iomem *regs, struct memac_cfg *cfg, |
---|
414 | phy_interface_t phy_if, u16 speed, bool slow_10g_if, |
---|
415 | u32 exceptions) |
---|
416 | { |
---|
417 | u32 tmp; |
---|
418 | |
---|
419 | /* Config */ |
---|
420 | tmp = 0; |
---|
421 | if (cfg->promiscuous_mode_enable) |
---|
422 | tmp |= CMD_CFG_PROMIS_EN; |
---|
423 | if (cfg->pause_ignore) |
---|
424 | tmp |= CMD_CFG_PAUSE_IGNORE; |
---|
425 | |
---|
426 | /* Payload length check disable */ |
---|
427 | tmp |= CMD_CFG_NO_LEN_CHK; |
---|
428 | /* Enable padding of frames in transmit direction */ |
---|
429 | tmp |= CMD_CFG_TX_PAD_EN; |
---|
430 | |
---|
431 | tmp |= CMD_CFG_CRC_FWD; |
---|
432 | |
---|
433 | iowrite32be(tmp, ®s->command_config); |
---|
434 | |
---|
435 | /* Max Frame Length */ |
---|
436 | iowrite32be((u32)cfg->max_frame_length, ®s->maxfrm); |
---|
437 | |
---|
438 | /* Pause Time */ |
---|
439 | iowrite32be((u32)cfg->pause_quanta, ®s->pause_quanta[0]); |
---|
440 | iowrite32be((u32)0, ®s->pause_thresh[0]); |
---|
441 | |
---|
442 | /* IF_MODE */ |
---|
443 | tmp = 0; |
---|
444 | switch (phy_if) { |
---|
445 | case PHY_INTERFACE_MODE_XGMII: |
---|
446 | tmp |= IF_MODE_XGMII; |
---|
447 | break; |
---|
448 | default: |
---|
449 | tmp |= IF_MODE_GMII; |
---|
450 | if (phy_if == PHY_INTERFACE_MODE_RGMII || |
---|
451 | phy_if == PHY_INTERFACE_MODE_RGMII_ID || |
---|
452 | phy_if == PHY_INTERFACE_MODE_RGMII_RXID || |
---|
453 | phy_if == PHY_INTERFACE_MODE_RGMII_TXID) |
---|
454 | tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO; |
---|
455 | } |
---|
456 | iowrite32be(tmp, ®s->if_mode); |
---|
457 | |
---|
458 | /* TX_FIFO_SECTIONS */ |
---|
459 | tmp = 0; |
---|
460 | if (phy_if == PHY_INTERFACE_MODE_XGMII) { |
---|
461 | if (slow_10g_if) { |
---|
462 | tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G | |
---|
463 | TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); |
---|
464 | } else { |
---|
465 | tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G | |
---|
466 | TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G); |
---|
467 | } |
---|
468 | } else { |
---|
469 | tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G | |
---|
470 | TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G); |
---|
471 | } |
---|
472 | iowrite32be(tmp, ®s->tx_fifo_sections); |
---|
473 | |
---|
474 | /* clear all pending events and set-up interrupts */ |
---|
475 | iowrite32be(0xffffffff, ®s->ievent); |
---|
476 | set_exception(regs, exceptions, true); |
---|
477 | |
---|
478 | return 0; |
---|
479 | } |
---|
480 | |
---|
481 | static void set_dflts(struct memac_cfg *cfg) |
---|
482 | { |
---|
483 | cfg->reset_on_init = false; |
---|
484 | cfg->promiscuous_mode_enable = false; |
---|
485 | cfg->pause_ignore = false; |
---|
486 | cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH; |
---|
487 | cfg->max_frame_length = DEFAULT_FRAME_LENGTH; |
---|
488 | cfg->pause_quanta = DEFAULT_PAUSE_QUANTA; |
---|
489 | } |
---|
490 | |
---|
491 | static u32 get_mac_addr_hash_code(u64 eth_addr) |
---|
492 | { |
---|
493 | u64 mask1, mask2; |
---|
494 | u32 xor_val = 0; |
---|
495 | u8 i, j; |
---|
496 | |
---|
497 | for (i = 0; i < 6; i++) { |
---|
498 | mask1 = eth_addr & (u64)0x01; |
---|
499 | eth_addr >>= 1; |
---|
500 | |
---|
501 | for (j = 0; j < 7; j++) { |
---|
502 | mask2 = eth_addr & (u64)0x01; |
---|
503 | mask1 ^= mask2; |
---|
504 | eth_addr >>= 1; |
---|
505 | } |
---|
506 | |
---|
507 | xor_val |= (mask1 << (5 - i)); |
---|
508 | } |
---|
509 | |
---|
510 | return xor_val; |
---|
511 | } |
---|
512 | |
---|
513 | static void setup_sgmii_internal_phy(struct fman_mac *memac, |
---|
514 | struct fixed_phy_status *fixed_link) |
---|
515 | { |
---|
516 | u16 tmp_reg16; |
---|
517 | |
---|
518 | if (WARN_ON(!memac->pcsphy)) |
---|
519 | return; |
---|
520 | |
---|
521 | /* SGMII mode */ |
---|
522 | tmp_reg16 = IF_MODE_SGMII_EN; |
---|
523 | if (!fixed_link) |
---|
524 | /* AN enable */ |
---|
525 | tmp_reg16 |= IF_MODE_USE_SGMII_AN; |
---|
526 | else { |
---|
527 | #ifndef __rtems__ |
---|
528 | switch (fixed_link->speed) { |
---|
529 | case 10: |
---|
530 | /* For 10M: IF_MODE[SPEED_10M] = 0 */ |
---|
531 | break; |
---|
532 | case 100: |
---|
533 | tmp_reg16 |= IF_MODE_SGMII_SPEED_100M; |
---|
534 | break; |
---|
535 | case 1000: /* fallthrough */ |
---|
536 | default: |
---|
537 | tmp_reg16 |= IF_MODE_SGMII_SPEED_1G; |
---|
538 | break; |
---|
539 | } |
---|
540 | if (!fixed_link->duplex) |
---|
541 | tmp_reg16 |= IF_MODE_SGMII_DUPLEX_HALF; |
---|
542 | #endif /* __rtems__ */ |
---|
543 | } |
---|
544 | phy_write(memac->pcsphy, MDIO_SGMII_IF_MODE, tmp_reg16); |
---|
545 | |
---|
546 | /* Device ability according to SGMII specification */ |
---|
547 | tmp_reg16 = MDIO_SGMII_DEV_ABIL_SGMII_MODE; |
---|
548 | phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16); |
---|
549 | |
---|
550 | /* Adjust link timer for SGMII - |
---|
551 | * According to Cisco SGMII specification the timer should be 1.6 ms. |
---|
552 | * The link_timer register is configured in units of the clock. |
---|
553 | * - When running as 1G SGMII, Serdes clock is 125 MHz, so |
---|
554 | * unit = 1 / (125*10^6 Hz) = 8 ns. |
---|
555 | * 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2*10^5 = 0x30d40 |
---|
556 | * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so |
---|
557 | * unit = 1 / (312.5*10^6 Hz) = 3.2 ns. |
---|
558 | * 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5*10^5 = 0x7a120. |
---|
559 | * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, |
---|
560 | * we always set up here a value of 2.5 SGMII. |
---|
561 | */ |
---|
562 | phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H); |
---|
563 | phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L); |
---|
564 | |
---|
565 | if (!fixed_link) |
---|
566 | /* Restart AN */ |
---|
567 | tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN; |
---|
568 | else |
---|
569 | /* AN disabled */ |
---|
570 | tmp_reg16 = SGMII_CR_DEF_VAL & ~SGMII_CR_AN_EN; |
---|
571 | phy_write(memac->pcsphy, 0x0, tmp_reg16); |
---|
572 | } |
---|
573 | |
---|
574 | static void setup_sgmii_internal_phy_base_x(struct fman_mac *memac) |
---|
575 | { |
---|
576 | u16 tmp_reg16; |
---|
577 | |
---|
578 | /* AN Device capability */ |
---|
579 | tmp_reg16 = MDIO_SGMII_DEV_ABIL_BASEX_MODE; |
---|
580 | phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16); |
---|
581 | |
---|
582 | /* Adjust link timer for SGMII - |
---|
583 | * For Serdes 1000BaseX auto-negotiation the timer should be 10 ms. |
---|
584 | * The link_timer register is configured in units of the clock. |
---|
585 | * - When running as 1G SGMII, Serdes clock is 125 MHz, so |
---|
586 | * unit = 1 / (125*10^6 Hz) = 8 ns. |
---|
587 | * 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0 |
---|
588 | * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so |
---|
589 | * unit = 1 / (312.5*10^6 Hz) = 3.2 ns. |
---|
590 | * 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08. |
---|
591 | * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII, |
---|
592 | * we always set up here a value of 2.5 SGMII. |
---|
593 | */ |
---|
594 | phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H_BASEX); |
---|
595 | phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L_BASEX); |
---|
596 | |
---|
597 | /* Restart AN */ |
---|
598 | tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN; |
---|
599 | phy_write(memac->pcsphy, 0x0, tmp_reg16); |
---|
600 | } |
---|
601 | |
---|
602 | static int check_init_parameters(struct fman_mac *memac) |
---|
603 | { |
---|
604 | if (memac->addr == 0) { |
---|
605 | pr_err("Ethernet MAC must have a valid MAC address\n"); |
---|
606 | return -EINVAL; |
---|
607 | } |
---|
608 | if (!memac->exception_cb) { |
---|
609 | pr_err("Uninitialized exception handler\n"); |
---|
610 | return -EINVAL; |
---|
611 | } |
---|
612 | if (!memac->event_cb) { |
---|
613 | pr_warn("Uninitialize event handler\n"); |
---|
614 | return -EINVAL; |
---|
615 | } |
---|
616 | |
---|
617 | return 0; |
---|
618 | } |
---|
619 | |
---|
620 | static int get_exception_flag(enum fman_mac_exceptions exception) |
---|
621 | { |
---|
622 | u32 bit_mask; |
---|
623 | |
---|
624 | switch (exception) { |
---|
625 | case FM_MAC_EX_10G_TX_ECC_ER: |
---|
626 | bit_mask = MEMAC_IMASK_TECC_ER; |
---|
627 | break; |
---|
628 | case FM_MAC_EX_10G_RX_ECC_ER: |
---|
629 | bit_mask = MEMAC_IMASK_RECC_ER; |
---|
630 | break; |
---|
631 | case FM_MAC_EX_TS_FIFO_ECC_ERR: |
---|
632 | bit_mask = MEMAC_IMASK_TSECC_ER; |
---|
633 | break; |
---|
634 | case FM_MAC_EX_MAGIC_PACKET_INDICATION: |
---|
635 | bit_mask = MEMAC_IMASK_MGI; |
---|
636 | break; |
---|
637 | default: |
---|
638 | bit_mask = 0; |
---|
639 | break; |
---|
640 | } |
---|
641 | |
---|
642 | return bit_mask; |
---|
643 | } |
---|
644 | |
---|
645 | static void memac_err_exception(void *handle) |
---|
646 | { |
---|
647 | struct fman_mac *memac = (struct fman_mac *)handle; |
---|
648 | struct memac_regs __iomem *regs = memac->regs; |
---|
649 | u32 event, imask; |
---|
650 | |
---|
651 | event = ioread32be(®s->ievent); |
---|
652 | imask = ioread32be(®s->imask); |
---|
653 | |
---|
654 | /* Imask include both error and notification/event bits. |
---|
655 | * Leaving only error bits enabled by imask. |
---|
656 | * The imask error bits are shifted by 16 bits offset from |
---|
657 | * their corresponding location in the ievent - hence the >> 16 |
---|
658 | */ |
---|
659 | event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); |
---|
660 | |
---|
661 | iowrite32be(event, ®s->ievent); |
---|
662 | |
---|
663 | if (event & MEMAC_IEVNT_TS_ECC_ER) |
---|
664 | memac->exception_cb(memac->dev_id, FM_MAC_EX_TS_FIFO_ECC_ERR); |
---|
665 | if (event & MEMAC_IEVNT_TX_ECC_ER) |
---|
666 | memac->exception_cb(memac->dev_id, FM_MAC_EX_10G_TX_ECC_ER); |
---|
667 | if (event & MEMAC_IEVNT_RX_ECC_ER) |
---|
668 | memac->exception_cb(memac->dev_id, FM_MAC_EX_10G_RX_ECC_ER); |
---|
669 | } |
---|
670 | |
---|
671 | static void memac_exception(void *handle) |
---|
672 | { |
---|
673 | struct fman_mac *memac = (struct fman_mac *)handle; |
---|
674 | struct memac_regs __iomem *regs = memac->regs; |
---|
675 | u32 event, imask; |
---|
676 | |
---|
677 | event = ioread32be(®s->ievent); |
---|
678 | imask = ioread32be(®s->imask); |
---|
679 | |
---|
680 | /* Imask include both error and notification/event bits. |
---|
681 | * Leaving only error bits enabled by imask. |
---|
682 | * The imask error bits are shifted by 16 bits offset from |
---|
683 | * their corresponding location in the ievent - hence the >> 16 |
---|
684 | */ |
---|
685 | event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16); |
---|
686 | |
---|
687 | iowrite32be(event, ®s->ievent); |
---|
688 | |
---|
689 | if (event & MEMAC_IEVNT_MGI) |
---|
690 | memac->exception_cb(memac->dev_id, |
---|
691 | FM_MAC_EX_MAGIC_PACKET_INDICATION); |
---|
692 | } |
---|
693 | |
---|
694 | static void free_init_resources(struct fman_mac *memac) |
---|
695 | { |
---|
696 | fman_unregister_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, |
---|
697 | FMAN_INTR_TYPE_ERR); |
---|
698 | |
---|
699 | fman_unregister_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, |
---|
700 | FMAN_INTR_TYPE_NORMAL); |
---|
701 | |
---|
702 | /* release the driver's group hash table */ |
---|
703 | free_hash_table(memac->multicast_addr_hash); |
---|
704 | memac->multicast_addr_hash = NULL; |
---|
705 | |
---|
706 | /* release the driver's individual hash table */ |
---|
707 | free_hash_table(memac->unicast_addr_hash); |
---|
708 | memac->unicast_addr_hash = NULL; |
---|
709 | } |
---|
710 | |
---|
711 | static bool is_init_done(struct memac_cfg *memac_drv_params) |
---|
712 | { |
---|
713 | /* Checks if mEMAC driver parameters were initialized */ |
---|
714 | if (!memac_drv_params) |
---|
715 | return true; |
---|
716 | |
---|
717 | return false; |
---|
718 | } |
---|
719 | |
---|
720 | int memac_enable(struct fman_mac *memac, enum comm_mode mode) |
---|
721 | { |
---|
722 | struct memac_regs __iomem *regs = memac->regs; |
---|
723 | u32 tmp; |
---|
724 | |
---|
725 | if (!is_init_done(memac->memac_drv_param)) |
---|
726 | return -EINVAL; |
---|
727 | |
---|
728 | tmp = ioread32be(®s->command_config); |
---|
729 | if (mode & COMM_MODE_RX) |
---|
730 | tmp |= CMD_CFG_RX_EN; |
---|
731 | if (mode & COMM_MODE_TX) |
---|
732 | tmp |= CMD_CFG_TX_EN; |
---|
733 | |
---|
734 | iowrite32be(tmp, ®s->command_config); |
---|
735 | |
---|
736 | return 0; |
---|
737 | } |
---|
738 | |
---|
739 | int memac_disable(struct fman_mac *memac, enum comm_mode mode) |
---|
740 | { |
---|
741 | struct memac_regs __iomem *regs = memac->regs; |
---|
742 | u32 tmp; |
---|
743 | |
---|
744 | if (!is_init_done(memac->memac_drv_param)) |
---|
745 | return -EINVAL; |
---|
746 | |
---|
747 | tmp = ioread32be(®s->command_config); |
---|
748 | if (mode & COMM_MODE_RX) |
---|
749 | tmp &= ~CMD_CFG_RX_EN; |
---|
750 | if (mode & COMM_MODE_TX) |
---|
751 | tmp &= ~CMD_CFG_TX_EN; |
---|
752 | |
---|
753 | iowrite32be(tmp, ®s->command_config); |
---|
754 | |
---|
755 | return 0; |
---|
756 | } |
---|
757 | |
---|
758 | int memac_set_promiscuous(struct fman_mac *memac, bool new_val) |
---|
759 | { |
---|
760 | struct memac_regs __iomem *regs = memac->regs; |
---|
761 | u32 tmp; |
---|
762 | |
---|
763 | if (!is_init_done(memac->memac_drv_param)) |
---|
764 | return -EINVAL; |
---|
765 | |
---|
766 | tmp = ioread32be(®s->command_config); |
---|
767 | if (new_val) |
---|
768 | tmp |= CMD_CFG_PROMIS_EN; |
---|
769 | else |
---|
770 | tmp &= ~CMD_CFG_PROMIS_EN; |
---|
771 | |
---|
772 | iowrite32be(tmp, ®s->command_config); |
---|
773 | |
---|
774 | return 0; |
---|
775 | } |
---|
776 | |
---|
777 | int memac_adjust_link(struct fman_mac *memac, u16 speed) |
---|
778 | { |
---|
779 | struct memac_regs __iomem *regs = memac->regs; |
---|
780 | u32 tmp; |
---|
781 | |
---|
782 | if (!is_init_done(memac->memac_drv_param)) |
---|
783 | return -EINVAL; |
---|
784 | |
---|
785 | tmp = ioread32be(®s->if_mode); |
---|
786 | |
---|
787 | /* Set full duplex */ |
---|
788 | tmp &= ~IF_MODE_HD; |
---|
789 | |
---|
790 | if (memac->phy_if == PHY_INTERFACE_MODE_RGMII) { |
---|
791 | /* Configure RGMII in manual mode */ |
---|
792 | tmp &= ~IF_MODE_RGMII_AUTO; |
---|
793 | tmp &= ~IF_MODE_RGMII_SP_MASK; |
---|
794 | /* Full duplex */ |
---|
795 | tmp |= IF_MODE_RGMII_FD; |
---|
796 | |
---|
797 | switch (speed) { |
---|
798 | case SPEED_1000: |
---|
799 | tmp |= IF_MODE_RGMII_1000; |
---|
800 | break; |
---|
801 | case SPEED_100: |
---|
802 | tmp |= IF_MODE_RGMII_100; |
---|
803 | break; |
---|
804 | case SPEED_10: |
---|
805 | tmp |= IF_MODE_RGMII_10; |
---|
806 | break; |
---|
807 | default: |
---|
808 | break; |
---|
809 | } |
---|
810 | } |
---|
811 | |
---|
812 | iowrite32be(tmp, ®s->if_mode); |
---|
813 | |
---|
814 | return 0; |
---|
815 | } |
---|
816 | |
---|
817 | int memac_cfg_max_frame_len(struct fman_mac *memac, u16 new_val) |
---|
818 | { |
---|
819 | if (is_init_done(memac->memac_drv_param)) |
---|
820 | return -EINVAL; |
---|
821 | |
---|
822 | memac->memac_drv_param->max_frame_length = new_val; |
---|
823 | |
---|
824 | return 0; |
---|
825 | } |
---|
826 | |
---|
827 | int memac_cfg_reset_on_init(struct fman_mac *memac, bool enable) |
---|
828 | { |
---|
829 | if (is_init_done(memac->memac_drv_param)) |
---|
830 | return -EINVAL; |
---|
831 | |
---|
832 | memac->memac_drv_param->reset_on_init = enable; |
---|
833 | |
---|
834 | return 0; |
---|
835 | } |
---|
836 | |
---|
837 | #ifndef __rtems__ |
---|
838 | int memac_cfg_fixed_link(struct fman_mac *memac, |
---|
839 | struct fixed_phy_status *fixed_link) |
---|
840 | { |
---|
841 | if (is_init_done(memac->memac_drv_param)) |
---|
842 | return -EINVAL; |
---|
843 | |
---|
844 | memac->memac_drv_param->fixed_link = fixed_link; |
---|
845 | |
---|
846 | return 0; |
---|
847 | } |
---|
848 | #endif /* __rtems__ */ |
---|
849 | |
---|
850 | int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority, |
---|
851 | u16 pause_time, u16 thresh_time) |
---|
852 | { |
---|
853 | struct memac_regs __iomem *regs = memac->regs; |
---|
854 | u32 tmp; |
---|
855 | |
---|
856 | if (!is_init_done(memac->memac_drv_param)) |
---|
857 | return -EINVAL; |
---|
858 | |
---|
859 | tmp = ioread32be(®s->tx_fifo_sections); |
---|
860 | |
---|
861 | GET_TX_EMPTY_DEFAULT_VALUE(tmp); |
---|
862 | iowrite32be(tmp, ®s->tx_fifo_sections); |
---|
863 | |
---|
864 | tmp = ioread32be(®s->command_config); |
---|
865 | tmp &= ~CMD_CFG_PFC_MODE; |
---|
866 | priority = 0; |
---|
867 | |
---|
868 | iowrite32be(tmp, ®s->command_config); |
---|
869 | |
---|
870 | tmp = ioread32be(®s->pause_quanta[priority / 2]); |
---|
871 | if (priority % 2) |
---|
872 | tmp &= CLXY_PAUSE_QUANTA_CLX_PQNT; |
---|
873 | else |
---|
874 | tmp &= CLXY_PAUSE_QUANTA_CLY_PQNT; |
---|
875 | tmp |= ((u32)pause_time << (16 * (priority % 2))); |
---|
876 | iowrite32be(tmp, ®s->pause_quanta[priority / 2]); |
---|
877 | |
---|
878 | tmp = ioread32be(®s->pause_thresh[priority / 2]); |
---|
879 | if (priority % 2) |
---|
880 | tmp &= CLXY_PAUSE_THRESH_CLX_QTH; |
---|
881 | else |
---|
882 | tmp &= CLXY_PAUSE_THRESH_CLY_QTH; |
---|
883 | tmp |= ((u32)thresh_time << (16 * (priority % 2))); |
---|
884 | iowrite32be(tmp, ®s->pause_thresh[priority / 2]); |
---|
885 | |
---|
886 | return 0; |
---|
887 | } |
---|
888 | |
---|
889 | int memac_accept_rx_pause_frames(struct fman_mac *memac, bool en) |
---|
890 | { |
---|
891 | struct memac_regs __iomem *regs = memac->regs; |
---|
892 | u32 tmp; |
---|
893 | |
---|
894 | if (!is_init_done(memac->memac_drv_param)) |
---|
895 | return -EINVAL; |
---|
896 | |
---|
897 | tmp = ioread32be(®s->command_config); |
---|
898 | if (en) |
---|
899 | tmp &= ~CMD_CFG_PAUSE_IGNORE; |
---|
900 | else |
---|
901 | tmp |= CMD_CFG_PAUSE_IGNORE; |
---|
902 | |
---|
903 | iowrite32be(tmp, ®s->command_config); |
---|
904 | |
---|
905 | return 0; |
---|
906 | } |
---|
907 | |
---|
908 | int memac_modify_mac_address(struct fman_mac *memac, enet_addr_t *enet_addr) |
---|
909 | { |
---|
910 | if (!is_init_done(memac->memac_drv_param)) |
---|
911 | return -EINVAL; |
---|
912 | |
---|
913 | add_addr_in_paddr(memac->regs, (u8 *)(*enet_addr), 0); |
---|
914 | |
---|
915 | return 0; |
---|
916 | } |
---|
917 | |
---|
918 | int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr) |
---|
919 | { |
---|
920 | struct memac_regs __iomem *regs = memac->regs; |
---|
921 | struct eth_hash_entry *hash_entry; |
---|
922 | u32 hash; |
---|
923 | u64 addr; |
---|
924 | |
---|
925 | if (!is_init_done(memac->memac_drv_param)) |
---|
926 | return -EINVAL; |
---|
927 | |
---|
928 | addr = ENET_ADDR_TO_UINT64(*eth_addr); |
---|
929 | |
---|
930 | if (!(addr & GROUP_ADDRESS)) { |
---|
931 | /* Unicast addresses not supported in hash */ |
---|
932 | pr_err("Unicast Address\n"); |
---|
933 | return -EINVAL; |
---|
934 | } |
---|
935 | hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK; |
---|
936 | |
---|
937 | /* Create element to be added to the driver hash table */ |
---|
938 | hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL); |
---|
939 | if (!hash_entry) |
---|
940 | return -ENOMEM; |
---|
941 | hash_entry->addr = addr; |
---|
942 | INIT_LIST_HEAD(&hash_entry->node); |
---|
943 | |
---|
944 | list_add_tail(&hash_entry->node, |
---|
945 | &memac->multicast_addr_hash->lsts[hash]); |
---|
946 | iowrite32be(hash | HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); |
---|
947 | |
---|
948 | return 0; |
---|
949 | } |
---|
950 | |
---|
951 | int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr) |
---|
952 | { |
---|
953 | struct memac_regs __iomem *regs = memac->regs; |
---|
954 | struct eth_hash_entry *hash_entry = NULL; |
---|
955 | struct list_head *pos; |
---|
956 | u32 hash; |
---|
957 | u64 addr; |
---|
958 | |
---|
959 | if (!is_init_done(memac->memac_drv_param)) |
---|
960 | return -EINVAL; |
---|
961 | |
---|
962 | addr = ENET_ADDR_TO_UINT64(*eth_addr); |
---|
963 | |
---|
964 | hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK; |
---|
965 | |
---|
966 | list_for_each(pos, &memac->multicast_addr_hash->lsts[hash]) { |
---|
967 | hash_entry = ETH_HASH_ENTRY_OBJ(pos); |
---|
968 | if (hash_entry->addr == addr) { |
---|
969 | list_del_init(&hash_entry->node); |
---|
970 | kfree(hash_entry); |
---|
971 | break; |
---|
972 | } |
---|
973 | } |
---|
974 | if (list_empty(&memac->multicast_addr_hash->lsts[hash])) |
---|
975 | iowrite32be(hash & ~HASH_CTRL_MCAST_EN, ®s->hashtable_ctrl); |
---|
976 | |
---|
977 | return 0; |
---|
978 | } |
---|
979 | |
---|
980 | int memac_set_exception(struct fman_mac *memac, |
---|
981 | enum fman_mac_exceptions exception, bool enable) |
---|
982 | { |
---|
983 | u32 bit_mask = 0; |
---|
984 | |
---|
985 | if (!is_init_done(memac->memac_drv_param)) |
---|
986 | return -EINVAL; |
---|
987 | |
---|
988 | bit_mask = get_exception_flag(exception); |
---|
989 | if (bit_mask) { |
---|
990 | if (enable) |
---|
991 | memac->exceptions |= bit_mask; |
---|
992 | else |
---|
993 | memac->exceptions &= ~bit_mask; |
---|
994 | } else { |
---|
995 | pr_err("Undefined exception\n"); |
---|
996 | return -EINVAL; |
---|
997 | } |
---|
998 | set_exception(memac->regs, bit_mask, enable); |
---|
999 | |
---|
1000 | return 0; |
---|
1001 | } |
---|
1002 | |
---|
1003 | int memac_init(struct fman_mac *memac) |
---|
1004 | { |
---|
1005 | struct memac_cfg *memac_drv_param; |
---|
1006 | u8 i; |
---|
1007 | enet_addr_t eth_addr; |
---|
1008 | bool slow_10g_if = false; |
---|
1009 | struct fixed_phy_status *fixed_link; |
---|
1010 | int err; |
---|
1011 | u32 reg32 = 0; |
---|
1012 | |
---|
1013 | if (is_init_done(memac->memac_drv_param)) |
---|
1014 | return -EINVAL; |
---|
1015 | |
---|
1016 | err = check_init_parameters(memac); |
---|
1017 | if (err) |
---|
1018 | return err; |
---|
1019 | |
---|
1020 | memac_drv_param = memac->memac_drv_param; |
---|
1021 | |
---|
1022 | if (memac->fm_rev_info.major == 6 && memac->fm_rev_info.minor == 4) |
---|
1023 | slow_10g_if = true; |
---|
1024 | |
---|
1025 | /* First, reset the MAC if desired. */ |
---|
1026 | if (memac_drv_param->reset_on_init) { |
---|
1027 | err = reset(memac->regs); |
---|
1028 | if (err) { |
---|
1029 | pr_err("mEMAC reset failed\n"); |
---|
1030 | return err; |
---|
1031 | } |
---|
1032 | } |
---|
1033 | |
---|
1034 | /* MAC Address */ |
---|
1035 | MAKE_ENET_ADDR_FROM_UINT64(memac->addr, eth_addr); |
---|
1036 | add_addr_in_paddr(memac->regs, (u8 *)eth_addr, 0); |
---|
1037 | |
---|
1038 | fixed_link = memac_drv_param->fixed_link; |
---|
1039 | |
---|
1040 | init(memac->regs, memac->memac_drv_param, memac->phy_if, |
---|
1041 | memac->max_speed, slow_10g_if, memac->exceptions); |
---|
1042 | |
---|
1043 | /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 errata workaround |
---|
1044 | * Exists only in FMan 6.0 and 6.3. |
---|
1045 | */ |
---|
1046 | if ((memac->fm_rev_info.major == 6) && |
---|
1047 | ((memac->fm_rev_info.minor == 0) || |
---|
1048 | (memac->fm_rev_info.minor == 3))) { |
---|
1049 | /* MAC strips CRC from received frames - this workaround |
---|
1050 | * should decrease the likelihood of bug appearance |
---|
1051 | */ |
---|
1052 | reg32 = ioread32be(&memac->regs->command_config); |
---|
1053 | reg32 &= ~CMD_CFG_CRC_FWD; |
---|
1054 | iowrite32be(reg32, &memac->regs->command_config); |
---|
1055 | } |
---|
1056 | |
---|
1057 | if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) { |
---|
1058 | /* Configure internal SGMII PHY */ |
---|
1059 | if (memac->basex_if) |
---|
1060 | setup_sgmii_internal_phy_base_x(memac); |
---|
1061 | else |
---|
1062 | setup_sgmii_internal_phy(memac, fixed_link); |
---|
1063 | } else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) { |
---|
1064 | /* Configure 4 internal SGMII PHYs */ |
---|
1065 | for (i = 0; i < 4; i++) { |
---|
1066 | u8 qsmgii_phy_addr, phy_addr; |
---|
1067 | /* QSGMII PHY address occupies 3 upper bits of 5-bit |
---|
1068 | * phy_address; the lower 2 bits are used to extend |
---|
1069 | * register address space and access each one of 4 |
---|
1070 | * ports inside QSGMII. |
---|
1071 | */ |
---|
1072 | phy_addr = memac->pcsphy->mdio.addr; |
---|
1073 | qsmgii_phy_addr = (u8)((phy_addr << 2) | i); |
---|
1074 | memac->pcsphy->mdio.addr = qsmgii_phy_addr; |
---|
1075 | if (memac->basex_if) |
---|
1076 | setup_sgmii_internal_phy_base_x(memac); |
---|
1077 | else |
---|
1078 | setup_sgmii_internal_phy(memac, fixed_link); |
---|
1079 | |
---|
1080 | memac->pcsphy->mdio.addr = phy_addr; |
---|
1081 | } |
---|
1082 | } |
---|
1083 | |
---|
1084 | /* Max Frame Length */ |
---|
1085 | err = fman_set_mac_max_frame(memac->fm, memac->mac_id, |
---|
1086 | memac_drv_param->max_frame_length); |
---|
1087 | if (err) { |
---|
1088 | pr_err("settings Mac max frame length is FAILED\n"); |
---|
1089 | return err; |
---|
1090 | } |
---|
1091 | |
---|
1092 | memac->multicast_addr_hash = alloc_hash_table(HASH_TABLE_SIZE); |
---|
1093 | if (!memac->multicast_addr_hash) { |
---|
1094 | free_init_resources(memac); |
---|
1095 | pr_err("allocation hash table is FAILED\n"); |
---|
1096 | return -ENOMEM; |
---|
1097 | } |
---|
1098 | |
---|
1099 | memac->unicast_addr_hash = alloc_hash_table(HASH_TABLE_SIZE); |
---|
1100 | if (!memac->unicast_addr_hash) { |
---|
1101 | free_init_resources(memac); |
---|
1102 | pr_err("allocation hash table is FAILED\n"); |
---|
1103 | return -ENOMEM; |
---|
1104 | } |
---|
1105 | |
---|
1106 | fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, |
---|
1107 | FMAN_INTR_TYPE_ERR, memac_err_exception, memac); |
---|
1108 | |
---|
1109 | fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id, |
---|
1110 | FMAN_INTR_TYPE_NORMAL, memac_exception, memac); |
---|
1111 | |
---|
1112 | kfree(memac_drv_param); |
---|
1113 | memac->memac_drv_param = NULL; |
---|
1114 | |
---|
1115 | return 0; |
---|
1116 | } |
---|
1117 | |
---|
1118 | int memac_free(struct fman_mac *memac) |
---|
1119 | { |
---|
1120 | free_init_resources(memac); |
---|
1121 | |
---|
1122 | if (memac->pcsphy) |
---|
1123 | put_device(&memac->pcsphy->mdio.dev); |
---|
1124 | |
---|
1125 | kfree(memac->memac_drv_param); |
---|
1126 | kfree(memac); |
---|
1127 | |
---|
1128 | return 0; |
---|
1129 | } |
---|
1130 | |
---|
1131 | struct fman_mac *memac_config(struct fman_mac_params *params) |
---|
1132 | { |
---|
1133 | struct fman_mac *memac; |
---|
1134 | struct memac_cfg *memac_drv_param; |
---|
1135 | void __iomem *base_addr; |
---|
1136 | |
---|
1137 | base_addr = params->base_addr; |
---|
1138 | /* allocate memory for the m_emac data structure */ |
---|
1139 | memac = kzalloc(sizeof(*memac), GFP_KERNEL); |
---|
1140 | if (!memac) |
---|
1141 | return NULL; |
---|
1142 | |
---|
1143 | /* allocate memory for the m_emac driver parameters data structure */ |
---|
1144 | memac_drv_param = kzalloc(sizeof(*memac_drv_param), GFP_KERNEL); |
---|
1145 | if (!memac_drv_param) { |
---|
1146 | memac_free(memac); |
---|
1147 | return NULL; |
---|
1148 | } |
---|
1149 | |
---|
1150 | /* Plant parameter structure pointer */ |
---|
1151 | memac->memac_drv_param = memac_drv_param; |
---|
1152 | |
---|
1153 | set_dflts(memac_drv_param); |
---|
1154 | |
---|
1155 | memac->addr = ENET_ADDR_TO_UINT64(params->addr); |
---|
1156 | |
---|
1157 | memac->regs = base_addr; |
---|
1158 | memac->max_speed = params->max_speed; |
---|
1159 | memac->phy_if = params->phy_if; |
---|
1160 | memac->mac_id = params->mac_id; |
---|
1161 | memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER | |
---|
1162 | MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI); |
---|
1163 | memac->exception_cb = params->exception_cb; |
---|
1164 | memac->event_cb = params->event_cb; |
---|
1165 | memac->dev_id = params->dev_id; |
---|
1166 | memac->fm = params->fm; |
---|
1167 | memac->basex_if = params->basex_if; |
---|
1168 | |
---|
1169 | /* Save FMan revision */ |
---|
1170 | fman_get_revision(memac->fm, &memac->fm_rev_info); |
---|
1171 | |
---|
1172 | if (memac->phy_if == PHY_INTERFACE_MODE_SGMII || |
---|
1173 | memac->phy_if == PHY_INTERFACE_MODE_QSGMII) { |
---|
1174 | if (!params->internal_phy_node) { |
---|
1175 | pr_err("PCS PHY node is not available\n"); |
---|
1176 | memac_free(memac); |
---|
1177 | return NULL; |
---|
1178 | } |
---|
1179 | |
---|
1180 | memac->pcsphy = of_phy_find_device(params->internal_phy_node); |
---|
1181 | if (!memac->pcsphy) { |
---|
1182 | pr_err("of_phy_find_device (PCS PHY) failed\n"); |
---|
1183 | memac_free(memac); |
---|
1184 | return NULL; |
---|
1185 | } |
---|
1186 | } |
---|
1187 | |
---|
1188 | return memac; |
---|
1189 | } |
---|