]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/mips/nlm/dev/net/xaui.c
MFV r319736: 6396 remove SVM
[FreeBSD/FreeBSD.git] / sys / mips / nlm / dev / net / xaui.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2003-2012 Broadcom Corporation
5  * All Rights Reserved
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33 #include <sys/types.h>
34 #include <sys/systm.h>
35
36 #include <mips/nlm/hal/mips-extns.h>
37 #include <mips/nlm/hal/haldefs.h>
38 #include <mips/nlm/hal/iomap.h>
39 #include <mips/nlm/hal/sys.h>
40 #include <mips/nlm/hal/nae.h>
41 #include <mips/nlm/hal/mdio.h>
42 #include <mips/nlm/hal/sgmii.h>
43 #include <mips/nlm/hal/xaui.h>
44
45 #include <mips/nlm/xlp.h>
46 void
47 nlm_xaui_pcs_init(uint64_t nae_base, int xaui_cplx_mask)
48 {
49         int block, lane_ctrl, reg;
50         int cplx_lane_enable;
51         int lane_enable = 0;
52         uint32_t regval;
53
54         cplx_lane_enable = LM_XAUI |
55             (LM_XAUI << 4) |
56             (LM_XAUI << 8) |
57             (LM_XAUI << 12);
58
59         if (xaui_cplx_mask == 0)
60                 return;
61
62         /* write 0x2 to enable SGMII for all lane */
63         block = 7;
64
65         if (xaui_cplx_mask & 0x3) { /* Complexes 0, 1 */
66                 lane_enable = nlm_read_nae_reg(nae_base,
67                     NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1));
68                 if (xaui_cplx_mask & 0x1) { /* Complex 0 */
69                         lane_enable &= ~(0xFFFF);
70                         lane_enable |= cplx_lane_enable;
71                 }
72                 if (xaui_cplx_mask & 0x2) { /* Complex 1 */
73                         lane_enable &= ~(0xFFFF<<16);
74                         lane_enable |= (cplx_lane_enable << 16);
75                 }
76                 nlm_write_nae_reg(nae_base,
77                     NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1),
78                     lane_enable);
79         }
80         lane_enable = 0;
81         if (xaui_cplx_mask & 0xc) { /* Complexes 2, 3 */
82                 lane_enable = nlm_read_nae_reg(nae_base,
83                     NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3));
84                 if (xaui_cplx_mask & 0x4) { /* Complex 2 */
85                         lane_enable &= ~(0xFFFF);
86                         lane_enable |= cplx_lane_enable;
87                 }
88                 if (xaui_cplx_mask & 0x8) { /* Complex 3 */
89                         lane_enable &= ~(0xFFFF<<16);
90                         lane_enable |= (cplx_lane_enable << 16);
91                 }
92                 nlm_write_nae_reg(nae_base,
93                     NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3),
94                     lane_enable);
95         }
96
97         /* Bring txpll out of reset */
98         for (block = 0; block < 4; block++) {
99                 if ((xaui_cplx_mask & (1 << block)) == 0)
100                         continue;
101
102                 for (lane_ctrl = PHY_LANE_0_CTRL;
103                     lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {
104                         if (!nlm_is_xlp8xx_ax())
105                                 xlp_nae_lane_reset_txpll(nae_base,
106                                     block, lane_ctrl, PHYMODE_XAUI);
107                         else
108                                 xlp_ax_nae_lane_reset_txpll(nae_base, block,
109                                     lane_ctrl, PHYMODE_XAUI);
110                 }
111         }
112
113         /* Wait for Rx & TX clock stable */
114         for (block = 0; block < 4; block++) {
115                 if ((xaui_cplx_mask & (1 << block)) == 0)
116                         continue;
117
118                 for (lane_ctrl = PHY_LANE_0_CTRL;
119                     lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) {
120
121                         reg = NAE_REG(block, PHY, lane_ctrl - 4);
122                         /* Wait for TX clock to be set */
123                         do {
124                                 regval = nlm_read_nae_reg(nae_base, reg);
125                         } while ((regval & LANE_TX_CLK) == 0);
126
127                         /* Wait for RX clock to be set */
128                         do {
129                                 regval = nlm_read_nae_reg(nae_base, reg);
130                         } while ((regval & LANE_RX_CLK) == 0);
131
132                         /* Wait for XAUI Lane fault to be cleared */
133                         do {
134                                 regval = nlm_read_nae_reg(nae_base, reg);
135                         } while ((regval & XAUI_LANE_FAULT) != 0);
136                 }
137         }
138 }
139
140 void
141 nlm_nae_setup_rx_mode_xaui(uint64_t base, int nblock, int iface, int port_type,
142     int broadcast_en, int multicast_en, int pause_en, int promisc_en)
143 {
144         uint32_t val;
145
146         val = ((broadcast_en & 0x1) << 10)  |
147             ((pause_en & 0x1) << 9)     |
148             ((multicast_en & 0x1) << 8) |
149             ((promisc_en & 0x1) << 7)   | /* unicast_enable - enables promisc mode */
150             1; /* MAC address is always valid */
151
152         nlm_write_nae_reg(base, XAUI_MAC_FILTER_CFG(nblock), val);
153 }
154
155 void
156 nlm_nae_setup_mac_addr_xaui(uint64_t base, int nblock, int iface,
157     int port_type, unsigned char *mac_addr)
158 {
159         nlm_write_nae_reg(base,
160             XAUI_MAC_ADDR0_LO(nblock),
161             (mac_addr[5] << 24) |
162             (mac_addr[4] << 16) |
163             (mac_addr[3] << 8)  |
164             mac_addr[2]);
165
166         nlm_write_nae_reg(base,
167             XAUI_MAC_ADDR0_HI(nblock),
168             (mac_addr[1] << 24) |
169             (mac_addr[0] << 16));
170
171         nlm_write_nae_reg(base,
172             XAUI_MAC_ADDR_MASK0_LO(nblock),
173             0xffffffff);
174         nlm_write_nae_reg(base,
175             XAUI_MAC_ADDR_MASK0_HI(nblock),
176             0xffffffff);
177
178         nlm_nae_setup_rx_mode_xaui(base, nblock, iface,
179             XAUIC,
180             1, /* broadcast enabled */
181             1, /* multicast enabled */
182             0, /* do not accept pause frames */
183             0 /* promisc mode disabled */
184             );
185 }
186
187 void
188 nlm_config_xaui_mtu(uint64_t nae_base, int nblock,
189     int max_tx_frame_sz, int max_rx_frame_sz)
190 {
191         uint32_t tx_words = max_tx_frame_sz >> 2; /* max_tx_frame_sz / 4 */
192
193         /* write max frame length */
194         nlm_write_nae_reg(nae_base,
195             XAUI_MAX_FRAME_LEN(nblock),
196             ((tx_words & 0x3ff) << 16) | (max_rx_frame_sz & 0xffff));
197 }
198
199 void
200 nlm_config_xaui(uint64_t nae_base, int nblock,
201     int max_tx_frame_sz, int max_rx_frame_sz, int vlan_pri_en)
202 {
203         uint32_t val;
204
205         val = nlm_read_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock));
206         val &= ~(0x1 << 11);    /* clear soft reset */
207         nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock), val);
208
209         val = nlm_read_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock));
210         val &= ~(0x3 << 11);    /* clear soft reset and hard reset */
211         nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock), val);
212         nlm_write_nae_reg(nae_base, XAUI_CONFIG0(nblock), 0xffffffff);
213         nlm_write_nae_reg(nae_base, XAUI_CONFIG0(nblock), 0);
214
215         /* Enable tx/rx frame */
216         val = 0x000010A8;
217         val |= XAUI_CONFIG_LENCHK;
218         val |= XAUI_CONFIG_GENFCS;
219         val |= XAUI_CONFIG_PAD_64;
220         nlm_write_nae_reg(nae_base, XAUI_CONFIG1(nblock), val);
221
222         /* write max frame length */
223         nlm_config_xaui_mtu(nae_base, nblock, max_tx_frame_sz,
224             max_rx_frame_sz);
225
226         /* set stats counter */
227         val = nlm_read_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock));
228         val |= (0x1 << NETIOR_XGMAC_VLAN_DC_POS);
229         val |= (0x1 << NETIOR_XGMAC_STATS_EN_POS);
230         if (vlan_pri_en) {
231                 val |= (0x1 << NETIOR_XGMAC_TX_PFC_EN_POS);
232                 val |= (0x1 << NETIOR_XGMAC_RX_PFC_EN_POS);
233                 val |= (0x1 << NETIOR_XGMAC_TX_PAUSE_POS);
234         } else {
235                 val &= ~(0x1 << NETIOR_XGMAC_TX_PFC_EN_POS);
236                 val |= (0x1 << NETIOR_XGMAC_TX_PAUSE_POS);
237         }
238         nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL1(nblock), val);
239         /* configure on / off timer */
240         if (vlan_pri_en)
241                 val = 0xF1230000; /* PFC mode, offtimer = 0xf123, ontimer = 0 */
242         else
243                 val = 0x0000F123; /* link level FC mode, offtimer = 0xf123 */
244         nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL2(nblock), val);
245
246         /* set xaui tx threshold */
247         val = nlm_read_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL3(nblock));
248         val &= ~(0x1f << 10);
249         val |= ~(15 << 10);
250         nlm_write_nae_reg(nae_base, XAUI_NETIOR_XGMAC_CTRL3(nblock), val);
251 }