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