xref: /freebsd-13-stable/sys/mips/nlm/dev/net/sgmii.c (revision 3bc80996974a61a4223eae4c1ccd47b6ee32a48a)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
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 #include <sys/types.h>
33 #include <sys/systm.h>
34 
35 #include <mips/nlm/hal/mips-extns.h>
36 #include <mips/nlm/hal/haldefs.h>
37 #include <mips/nlm/hal/iomap.h>
38 #include <mips/nlm/hal/sys.h>
39 #include <mips/nlm/hal/nae.h>
40 #include <mips/nlm/hal/mdio.h>
41 #include <mips/nlm/hal/sgmii.h>
42 
43 void
nlm_configure_sgmii_interface(uint64_t nae_base,int block,int port,int mtu,int loopback)44 nlm_configure_sgmii_interface(uint64_t nae_base, int block, int port,
45     int mtu, int loopback)
46 {
47 	uint32_t data1, data2;
48 
49 	/* Apply a soft reset */
50 	data1 = (0x1 << 31); /* soft reset */
51 	if (loopback)
52 		data1 |= (0x01 << 8);
53 	data1 |= (0x01 << 2); /* Rx enable */
54 	data1 |= 0x01; /* Tx enable */
55 	nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF1), data1);
56 
57 	data2 = (0x7 << 12) | /* pre-amble length=7 */
58 	    (0x2 << 8) | /* byteMode */
59 	    0x1;         /* fullDuplex */
60 	nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF2), data2);
61 
62 	/* Remove a soft reset */
63 	data1 &= ~(0x01 << 31);
64 	nlm_write_nae_reg(nae_base, NAE_REG(block, port, MAC_CONF1), data1);
65 
66 	/* setup sgmii max frame length */
67 	nlm_write_nae_reg(nae_base, SGMII_MAX_FRAME(block, port), mtu);
68 }
69 
70 void
nlm_sgmii_pcs_init(uint64_t nae_base,uint32_t cplx_mask)71 nlm_sgmii_pcs_init(uint64_t nae_base, uint32_t cplx_mask)
72 {
73 	xlp_nae_config_lane_gmac(nae_base, cplx_mask);
74 }
75 
76 void
nlm_nae_setup_mac(uint64_t nae_base,int nblock,int iface,int reset,int rx_en,int tx_en,int speed,int duplex)77 nlm_nae_setup_mac(uint64_t nae_base, int nblock, int iface, int reset,
78     int rx_en, int tx_en, int speed, int duplex)
79 {
80 	uint32_t mac_cfg1, mac_cfg2, netwk_inf;
81 
82 	mac_cfg1 = nlm_read_nae_reg(nae_base,
83 	    SGMII_MAC_CONF1(nblock,iface));
84 	mac_cfg2 = nlm_read_nae_reg(nae_base,
85 	    SGMII_MAC_CONF2(nblock,iface));
86 	netwk_inf = nlm_read_nae_reg(nae_base,
87 	    SGMII_NET_IFACE_CTRL(nblock, iface));
88 
89 	mac_cfg1 &= ~(0x1 << 31); /* remove reset */
90 	mac_cfg1 &= ~(0x1 << 2); /* remove rx */
91 	mac_cfg1 &= ~(0x1); /* remove tx */
92 	mac_cfg2 &= ~(0x3 << 8); /* remove interface mode bits */
93 	mac_cfg2 &= ~(0x1); /* remove duplex */
94 	netwk_inf &= ~(0x1 << 2); /* remove tx */
95 	netwk_inf &= ~(0x3); /* remove speed */
96 
97 	switch (speed) {
98 	case NLM_SGMII_SPEED_10:
99 		netwk_inf |= 0x0; /* 2.5 Mhz clock for 10 Mbps */
100 		mac_cfg2  |= (0x1 << 8); /* enable 10/100 Mbps */
101 		break;
102 	case NLM_SGMII_SPEED_100:
103 		netwk_inf |= 0x1; /* 25 Mhz clock for 100 Mbps */
104 		mac_cfg2  |= (0x1 << 8); /* enable 10/100 Mbps */
105 		break;
106 	default: /* make it as 1G */
107 		netwk_inf |= 0x2; /* 125 Mhz clock for 1G */
108 		mac_cfg2  |= (0x2 << 8); /* enable 1G */
109 		break;
110 	}
111 
112 	if (reset)
113 		mac_cfg1 |= (0x1 << 31); /* set reset */
114 
115 	if (rx_en)
116 		mac_cfg1 |= (0x1 << 2); /* set rx */
117 
118         nlm_write_nae_reg(nae_base,
119 	    SGMII_NET_IFACE_CTRL(nblock, iface),
120 	    netwk_inf);
121 
122 	if (tx_en) {
123 		mac_cfg1 |= 0x1; /* set tx */
124 		netwk_inf |= (0x1 << 2); /* set tx */
125 	}
126 
127 	switch (duplex) {
128 	case NLM_SGMII_DUPLEX_HALF:
129 		/* duplexity is already set to half duplex */
130 		break;
131 	default:
132 		mac_cfg2 |= 0x1; /* set full duplex */
133 	}
134 
135 	nlm_write_nae_reg(nae_base, SGMII_MAC_CONF1(nblock, iface), mac_cfg1);
136 	nlm_write_nae_reg(nae_base, SGMII_MAC_CONF2(nblock, iface), mac_cfg2);
137 	nlm_write_nae_reg(nae_base, SGMII_NET_IFACE_CTRL(nblock, iface),
138 	    netwk_inf);
139 }
140 
141 void
nlm_nae_setup_rx_mode_sgmii(uint64_t base,int nblock,int iface,int port_type,int broadcast_en,int multicast_en,int pause_en,int promisc_en)142 nlm_nae_setup_rx_mode_sgmii(uint64_t base, int nblock, int iface, int port_type,
143     int broadcast_en, int multicast_en, int pause_en, int promisc_en)
144 {
145 	uint32_t val;
146 
147 	/* bit[17] of vlan_typefilter - allows packet matching in MAC.
148 	 * When DA filtering is disabled, this bit and bit[16] should
149 	 * be zero.
150 	 * bit[16] of vlan_typefilter - Allows hash matching to be used
151 	 * for DA filtering. When DA filtering is disabled, this bit and
152 	 * bit[17] should be zero.
153 	 * Both bits have to be set only if you want to turn on both
154 	 * features / modes.
155 	 */
156 	if (promisc_en == 1) {
157 		val = nlm_read_nae_reg(base,
158 		    SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface));
159 		val &= (~(0x3 << 16));
160 		nlm_write_nae_reg(base,
161 		    SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface), val);
162 	} else {
163 		val = nlm_read_nae_reg(base,
164 		    SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface));
165 		val |= (0x1 << 17);
166 		nlm_write_nae_reg(base,
167 		    SGMII_NETIOR_VLANTYPE_FILTER(nblock, iface), val);
168 	}
169 
170 	val = ((broadcast_en & 0x1) << 10)  |
171 	    ((pause_en & 0x1) << 9)     |
172 	    ((multicast_en & 0x1) << 8) |
173 	    ((promisc_en & 0x1) << 7)   | /* unicast_enable - enables promisc mode */
174 	    1; /* MAC address is always valid */
175 
176 	nlm_write_nae_reg(base, SGMII_MAC_FILTER_CONFIG(nblock, iface), val);
177 
178 }
179 
180 void
nlm_nae_setup_mac_addr_sgmii(uint64_t base,int nblock,int iface,int port_type,uint8_t * mac_addr)181 nlm_nae_setup_mac_addr_sgmii(uint64_t base, int nblock, int iface,
182     int port_type, uint8_t *mac_addr)
183 {
184 	nlm_write_nae_reg(base,
185 	    SGMII_MAC_ADDR0_LO(nblock, iface),
186 	    (mac_addr[5] << 24) |
187 	    (mac_addr[4] << 16) |
188 	    (mac_addr[3] << 8)  |
189 	    mac_addr[2]);
190 
191 	nlm_write_nae_reg(base,
192 	    SGMII_MAC_ADDR0_HI(nblock, iface),
193 	    (mac_addr[1] << 24) |
194 	    (mac_addr[0] << 16));
195 
196 	nlm_write_nae_reg(base,
197 	    SGMII_MAC_ADDR_MASK0_LO(nblock, iface),
198 	    0xffffffff);
199 	nlm_write_nae_reg(base,
200 	    SGMII_MAC_ADDR_MASK0_HI(nblock, iface),
201 	    0xffffffff);
202 
203 	nlm_nae_setup_rx_mode_sgmii(base, nblock, iface,
204 	    SGMIIC,
205 	    1, /* broadcast enabled */
206 	    1, /* multicast enabled */
207 	    0, /* do not accept pause frames */
208 	    0 /* promisc mode disabled */
209 	    );
210 }
211