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