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