1233545Sjchandra/*- 2233545Sjchandra * Copyright (c) 2003-2012 Broadcom Corporation 3233545Sjchandra * All Rights Reserved 4233545Sjchandra * 5233545Sjchandra * Redistribution and use in source and binary forms, with or without 6233545Sjchandra * modification, are permitted provided that the following conditions 7233545Sjchandra * are met: 8233545Sjchandra * 9233545Sjchandra * 1. Redistributions of source code must retain the above copyright 10233545Sjchandra * notice, this list of conditions and the following disclaimer. 11233545Sjchandra * 2. Redistributions in binary form must reproduce the above copyright 12233545Sjchandra * notice, this list of conditions and the following disclaimer in 13233545Sjchandra * the documentation and/or other materials provided with the 14233545Sjchandra * distribution. 15233545Sjchandra * 16233545Sjchandra * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR 17233545Sjchandra * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18233545Sjchandra * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19233545Sjchandra * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE 20233545Sjchandra * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21233545Sjchandra * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22233545Sjchandra * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23233545Sjchandra * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24233545Sjchandra * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25233545Sjchandra * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26233545Sjchandra * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27233545Sjchandra */ 28233545Sjchandra 29233545Sjchandra#include <sys/cdefs.h> 30233545Sjchandra__FBSDID("$FreeBSD$"); 31233545Sjchandra#include <sys/types.h> 32233545Sjchandra#include <sys/systm.h> 33233545Sjchandra 34233545Sjchandra#include <mips/nlm/hal/mips-extns.h> 35233545Sjchandra#include <mips/nlm/hal/haldefs.h> 36233545Sjchandra#include <mips/nlm/hal/iomap.h> 37233545Sjchandra#include <mips/nlm/hal/sys.h> 38233545Sjchandra#include <mips/nlm/hal/nae.h> 39233545Sjchandra#include <mips/nlm/hal/mdio.h> 40233545Sjchandra#include <mips/nlm/hal/sgmii.h> 41233545Sjchandra#include <mips/nlm/hal/xaui.h> 42233545Sjchandra 43233545Sjchandra#include <mips/nlm/board.h> 44233545Sjchandra#include <mips/nlm/xlp.h> 45233545Sjchandra 46233545Sjchandravoid 47233545Sjchandranlm_nae_flush_free_fifo(uint64_t nae_base, int nblocks) 48233545Sjchandra{ 49233545Sjchandra uint32_t data, fifo_mask; 50233545Sjchandra 51233545Sjchandra fifo_mask = (1 << (4 * nblocks)) - 1; 52233545Sjchandra 53233545Sjchandra nlm_write_nae_reg(nae_base, NAE_RX_FREE_FIFO_POP, fifo_mask); 54233545Sjchandra do { 55233545Sjchandra data = nlm_read_nae_reg(nae_base, NAE_RX_FREE_FIFO_POP); 56233545Sjchandra } while (data != fifo_mask); 57233545Sjchandra 58233545Sjchandra nlm_write_nae_reg(nae_base, NAE_RX_FREE_FIFO_POP, 0); 59233545Sjchandra} 60233545Sjchandra 61233545Sjchandravoid 62255368Sjchandranlm_program_nae_parser_seq_fifo(uint64_t nae_base, int maxports, 63233545Sjchandra struct nae_port_config *cfg) 64233545Sjchandra{ 65233545Sjchandra uint32_t val; 66255368Sjchandra int start = 0, size, i; 67233545Sjchandra 68255368Sjchandra for (i = 0; i < maxports; i++) { 69255368Sjchandra size = cfg[i].pseq_fifo_size; 70233545Sjchandra val = (((size & 0x1fff) << 17) | 71233545Sjchandra ((start & 0xfff) << 5) | 72255368Sjchandra (i & 0x1f)); 73233545Sjchandra nlm_write_nae_reg(nae_base, NAE_PARSER_SEQ_FIFO_CFG, val); 74233545Sjchandra start += size; 75233545Sjchandra } 76233545Sjchandra} 77233545Sjchandra 78233545Sjchandravoid 79233545Sjchandranlm_setup_rx_cal_cfg(uint64_t nae_base, int total_num_ports, 80233545Sjchandra struct nae_port_config *cfg) 81233545Sjchandra{ 82233545Sjchandra int rx_slots = 0, port; 83233545Sjchandra int cal_len, cal = 0, last_free = 0; 84233545Sjchandra uint32_t val; 85233545Sjchandra 86233545Sjchandra for (port = 0; port < total_num_ports; port++) { 87233545Sjchandra if (cfg[port].rx_slots_reqd) 88233545Sjchandra rx_slots += cfg[port].rx_slots_reqd; 89233545Sjchandra if (rx_slots > MAX_CAL_SLOTS) { 90233545Sjchandra rx_slots = MAX_CAL_SLOTS; 91233545Sjchandra break; 92233545Sjchandra } 93233545Sjchandra } 94233545Sjchandra 95233545Sjchandra cal_len = rx_slots - 1; 96233545Sjchandra 97233545Sjchandra do { 98233545Sjchandra if (cal >= MAX_CAL_SLOTS) 99233545Sjchandra break; 100233545Sjchandra last_free = cal; 101233545Sjchandra for (port = 0; port < total_num_ports; port++) { 102233545Sjchandra if (cfg[port].rx_slots_reqd > 0) { 103233545Sjchandra val = (cal_len << 16) | (port << 8) | cal; 104233545Sjchandra nlm_write_nae_reg(nae_base, 105233545Sjchandra NAE_RX_IF_SLOT_CAL, val); 106233545Sjchandra cal++; 107233545Sjchandra cfg[port].rx_slots_reqd--; 108233545Sjchandra } 109233545Sjchandra } 110233545Sjchandra if (last_free == cal) 111233545Sjchandra break; 112233545Sjchandra } while (1); 113233545Sjchandra} 114233545Sjchandra 115233545Sjchandravoid 116233545Sjchandranlm_setup_tx_cal_cfg(uint64_t nae_base, int total_num_ports, 117233545Sjchandra struct nae_port_config *cfg) 118233545Sjchandra{ 119233545Sjchandra int tx_slots = 0, port; 120233545Sjchandra int cal = 0, last_free = 0; 121233545Sjchandra uint32_t val; 122233545Sjchandra 123233545Sjchandra for (port = 0; port < total_num_ports; port++) { 124233545Sjchandra if (cfg[port].tx_slots_reqd) 125233545Sjchandra tx_slots += cfg[port].tx_slots_reqd; 126233545Sjchandra if (tx_slots > MAX_CAL_SLOTS) { 127233545Sjchandra tx_slots = MAX_CAL_SLOTS; 128233545Sjchandra break; 129233545Sjchandra } 130233545Sjchandra } 131233545Sjchandra 132233545Sjchandra nlm_write_nae_reg(nae_base, NAE_EGR_NIOR_CAL_LEN_REG, tx_slots - 1); 133233545Sjchandra do { 134233545Sjchandra if (cal >= MAX_CAL_SLOTS) 135233545Sjchandra break; 136233545Sjchandra last_free = cal; 137233545Sjchandra for (port = 0; port < total_num_ports; port++) { 138233545Sjchandra if (cfg[port].tx_slots_reqd > 0) { 139233545Sjchandra val = (port << 7) | (cal << 1) | 1; 140233545Sjchandra nlm_write_nae_reg(nae_base, 141233545Sjchandra NAE_EGR_NIOR_CRDT_CAL_PROG, val); 142233545Sjchandra cal++; 143233545Sjchandra cfg[port].tx_slots_reqd--; 144233545Sjchandra } 145233545Sjchandra } 146233545Sjchandra if (last_free == cal) 147233545Sjchandra break; 148233545Sjchandra } while (1); 149233545Sjchandra} 150233545Sjchandra 151233545Sjchandravoid 152233545Sjchandranlm_deflate_frin_fifo_carving(uint64_t nae_base, int total_num_ports) 153233545Sjchandra{ 154233545Sjchandra const int minimum_size = 8; 155233545Sjchandra uint32_t value; 156233545Sjchandra int intf, start; 157233545Sjchandra 158233545Sjchandra for (intf = 0; intf < total_num_ports; intf++) { 159233545Sjchandra start = minimum_size * intf; 160233545Sjchandra value = (minimum_size << 20) | (start << 8) | (intf); 161233545Sjchandra nlm_write_nae_reg(nae_base, NAE_FREE_IN_FIFO_CFG, value); 162233545Sjchandra } 163233545Sjchandra} 164233545Sjchandra 165233545Sjchandravoid 166233545Sjchandranlm_reset_nae(int node) 167233545Sjchandra{ 168233545Sjchandra uint64_t sysbase; 169233545Sjchandra uint64_t nae_base; 170233545Sjchandra uint64_t nae_pcibase; 171233545Sjchandra uint32_t rx_config; 172233545Sjchandra uint32_t bar0; 173233545Sjchandra int reset_bit; 174233545Sjchandra 175233545Sjchandra sysbase = nlm_get_sys_regbase(node); 176233545Sjchandra nae_base = nlm_get_nae_regbase(node); 177233545Sjchandra nae_pcibase = nlm_get_nae_pcibase(node); 178233545Sjchandra 179233545Sjchandra bar0 = nlm_read_pci_reg(nae_pcibase, XLP_PCI_CFGREG4); 180233545Sjchandra 181233545Sjchandra#if BYTE_ORDER == LITTLE_ENDIAN 182233545Sjchandra if (nlm_is_xlp8xx_ax()) { 183233636Sjmallett uint8_t val; 184233545Sjchandra /* membar fixup */ 185233545Sjchandra val = (bar0 >> 24) & 0xff; 186233545Sjchandra bar0 = (val << 24) | (val << 16) | (val << 8) | val; 187233545Sjchandra } 188233545Sjchandra#endif 189233545Sjchandra 190233545Sjchandra if (nlm_is_xlp3xx()) 191233545Sjchandra reset_bit = 6; 192233545Sjchandra else 193233545Sjchandra reset_bit = 9; 194233545Sjchandra 195233545Sjchandra /* Reset NAE */ 196233545Sjchandra nlm_write_sys_reg(sysbase, SYS_RESET, (1 << reset_bit)); 197233545Sjchandra 198233545Sjchandra /* XXXJC - 1s delay here may be too high */ 199233545Sjchandra DELAY(1000000); 200233545Sjchandra nlm_write_sys_reg(sysbase, SYS_RESET, (0 << reset_bit)); 201233545Sjchandra DELAY(1000000); 202233545Sjchandra 203233545Sjchandra rx_config = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG); 204233545Sjchandra nlm_write_pci_reg(nae_pcibase, XLP_PCI_CFGREG4, bar0); 205233545Sjchandra} 206233545Sjchandra 207233545Sjchandravoid 208233545Sjchandranlm_setup_poe_class_config(uint64_t nae_base, int max_poe_classes, 209233545Sjchandra int num_contexts, int *poe_cl_tbl) 210233545Sjchandra{ 211233545Sjchandra uint32_t val; 212233545Sjchandra int i, max_poe_class_ctxt_tbl_sz; 213233545Sjchandra 214233545Sjchandra max_poe_class_ctxt_tbl_sz = num_contexts/max_poe_classes; 215233545Sjchandra for (i = 0; i < max_poe_class_ctxt_tbl_sz; i++) { 216233545Sjchandra val = (poe_cl_tbl[(i/max_poe_classes) & 0x7] << 8) | i; 217233545Sjchandra nlm_write_nae_reg(nae_base, NAE_POE_CLASS_SETUP_CFG, val); 218233545Sjchandra } 219233545Sjchandra} 220233545Sjchandra 221233545Sjchandravoid 222233545Sjchandranlm_setup_vfbid_mapping(uint64_t nae_base) 223233545Sjchandra{ 224233545Sjchandra uint32_t val; 225233545Sjchandra int dest_vc, vfbid; 226233545Sjchandra 227233545Sjchandra /* 127 is max vfbid */ 228233545Sjchandra for (vfbid = 127; vfbid >= 0; vfbid--) { 229233545Sjchandra dest_vc = nlm_get_vfbid_mapping(vfbid); 230233545Sjchandra if (dest_vc < 0) 231233545Sjchandra continue; 232233545Sjchandra val = (dest_vc << 16) | (vfbid << 4) | 1; 233233545Sjchandra nlm_write_nae_reg(nae_base, NAE_VFBID_DESTMAP_CMD, val); 234233545Sjchandra } 235233545Sjchandra} 236233545Sjchandra 237233545Sjchandravoid 238233545Sjchandranlm_setup_flow_crc_poly(uint64_t nae_base, uint32_t poly) 239233545Sjchandra{ 240233545Sjchandra nlm_write_nae_reg(nae_base, NAE_FLOW_CRC16_POLY_CFG, poly); 241233545Sjchandra} 242233545Sjchandra 243233545Sjchandravoid 244255368Sjchandranlm_setup_iface_fifo_cfg(uint64_t nae_base, int maxports, 245233545Sjchandra struct nae_port_config *cfg) 246233545Sjchandra{ 247233545Sjchandra uint32_t reg; 248233545Sjchandra int fifo_xoff_thresh = 12; 249255368Sjchandra int i, size; 250233545Sjchandra int cur_iface_start = 0; 251233545Sjchandra 252255368Sjchandra for (i = 0; i < maxports; i++) { 253255368Sjchandra size = cfg[i].iface_fifo_size; 254233545Sjchandra reg = ((fifo_xoff_thresh << 25) | 255233545Sjchandra ((size & 0x1ff) << 16) | 256233545Sjchandra ((cur_iface_start & 0xff) << 8) | 257255368Sjchandra (i & 0x1f)); 258233545Sjchandra nlm_write_nae_reg(nae_base, NAE_IFACE_FIFO_CFG, reg); 259233545Sjchandra cur_iface_start += size; 260233545Sjchandra } 261233545Sjchandra} 262233545Sjchandra 263233545Sjchandravoid 264255368Sjchandranlm_setup_rx_base_config(uint64_t nae_base, int maxports, 265233545Sjchandra struct nae_port_config *cfg) 266233545Sjchandra{ 267233545Sjchandra int base = 0; 268255368Sjchandra uint32_t val; 269255368Sjchandra int i; 270233545Sjchandra int id; 271233545Sjchandra 272255368Sjchandra for (i = 0; i < (maxports/2); i++) { 273255368Sjchandra id = 0x12 + i; /* RX_IF_BASE_CONFIG0 */ 274233545Sjchandra 275233545Sjchandra val = (base & 0x3ff); 276255368Sjchandra base += cfg[(i * 2)].num_channels; 277233545Sjchandra 278233545Sjchandra val |= ((base & 0x3ff) << 16); 279255368Sjchandra base += cfg[(i * 2) + 1].num_channels; 280233545Sjchandra 281255368Sjchandra nlm_write_nae_reg(nae_base, NAE_REG(7, 0, id), val); 282233545Sjchandra } 283233545Sjchandra} 284233545Sjchandra 285233545Sjchandravoid 286255368Sjchandranlm_setup_rx_buf_config(uint64_t nae_base, int maxports, 287233545Sjchandra struct nae_port_config *cfg) 288233545Sjchandra{ 289233545Sjchandra uint32_t val; 290255368Sjchandra int i, sz, k; 291233545Sjchandra int context = 0; 292233545Sjchandra int base = 0; 293233545Sjchandra 294255368Sjchandra for (i = 0; i < maxports; i++) { 295255368Sjchandra if (cfg[i].type == UNKNOWN) 296255368Sjchandra continue; 297255368Sjchandra for (k = 0; k < cfg[i].num_channels; k++) { 298233545Sjchandra /* write index (context num) */ 299233545Sjchandra nlm_write_nae_reg(nae_base, NAE_RXBUF_BASE_DPTH_ADDR, 300233545Sjchandra (context+k)); 301233545Sjchandra 302233545Sjchandra /* write value (rx buf sizes) */ 303255368Sjchandra sz = cfg[i].rxbuf_size; 304233545Sjchandra val = 0x80000000 | ((base << 2) & 0x3fff); /* base */ 305233545Sjchandra val |= (((sz << 2) & 0x3fff) << 16); /* size */ 306233545Sjchandra 307233545Sjchandra nlm_write_nae_reg(nae_base, NAE_RXBUF_BASE_DPTH, val); 308233545Sjchandra nlm_write_nae_reg(nae_base, NAE_RXBUF_BASE_DPTH, 309233545Sjchandra (0x7fffffff & val)); 310233545Sjchandra base += sz; 311233545Sjchandra } 312255368Sjchandra context += cfg[i].num_channels; 313233545Sjchandra } 314233545Sjchandra} 315233545Sjchandra 316233545Sjchandravoid 317255368Sjchandranlm_setup_freein_fifo_cfg(uint64_t nae_base, struct nae_port_config *cfg) 318233545Sjchandra{ 319255368Sjchandra int size, i; 320233545Sjchandra uint32_t reg; 321255368Sjchandra int start = 0, maxbufpool; 322233545Sjchandra 323255368Sjchandra if (nlm_is_xlp8xx()) 324255368Sjchandra maxbufpool = MAX_FREE_FIFO_POOL_8XX; 325255368Sjchandra else 326255368Sjchandra maxbufpool = MAX_FREE_FIFO_POOL_3XX; 327255368Sjchandra for (i = 0; i < maxbufpool; i++) { 328233545Sjchandra /* Each entry represents 2 descs; hence division by 2 */ 329255368Sjchandra size = (cfg[i].num_free_descs / 2); 330233545Sjchandra if (size == 0) 331233545Sjchandra size = 8; 332233545Sjchandra reg = ((size & 0x3ff ) << 20) | /* fcSize */ 333233545Sjchandra ((start & 0x1ff) << 8) | /* fcStart */ 334255368Sjchandra (i & 0x1f); 335233545Sjchandra 336233545Sjchandra nlm_write_nae_reg(nae_base, NAE_FREE_IN_FIFO_CFG, reg); 337233545Sjchandra start += size; 338233545Sjchandra } 339233545Sjchandra} 340233545Sjchandra 341233545Sjchandra/* XXX function name */ 342233545Sjchandraint 343233545Sjchandranlm_get_flow_mask(int num_ports) 344233545Sjchandra{ 345233545Sjchandra const int max_bits = 5; /* upto 32 ports */ 346233545Sjchandra int i; 347233545Sjchandra 348233545Sjchandra /* Compute the number of bits to needed to 349233545Sjchandra * represent all the ports */ 350233545Sjchandra for (i = 0; i < max_bits; i++) { 351233545Sjchandra if (num_ports <= (2 << i)) 352233545Sjchandra return (i + 1); 353233545Sjchandra } 354233545Sjchandra return (max_bits); 355233545Sjchandra} 356233545Sjchandra 357233545Sjchandravoid 358233545Sjchandranlm_program_flow_cfg(uint64_t nae_base, int port, 359233545Sjchandra uint32_t cur_flow_base, uint32_t flow_mask) 360233545Sjchandra{ 361233545Sjchandra uint32_t val; 362233545Sjchandra 363233545Sjchandra val = (cur_flow_base << 16) | port; 364233545Sjchandra val |= ((flow_mask & 0x1f) << 8); 365233545Sjchandra nlm_write_nae_reg(nae_base, NAE_FLOW_BASEMASK_CFG, val); 366233545Sjchandra} 367233545Sjchandra 368233545Sjchandravoid 369233545Sjchandraxlp_ax_nae_lane_reset_txpll(uint64_t nae_base, int block, int lane_ctrl, 370233545Sjchandra int mode) 371233545Sjchandra{ 372233545Sjchandra uint32_t val = 0, saved_data; 373233545Sjchandra int rext_sel = 0; 374233545Sjchandra 375233545Sjchandra val = PHY_LANE_CTRL_RST | 376233545Sjchandra PHY_LANE_CTRL_PWRDOWN | 377233545Sjchandra (mode << PHY_LANE_CTRL_PHYMODE_POS); 378233545Sjchandra 379233545Sjchandra /* set comma bypass for XAUI */ 380233545Sjchandra if (mode != PHYMODE_SGMII) 381233545Sjchandra val |= PHY_LANE_CTRL_BPC_XAUI; 382233545Sjchandra 383233545Sjchandra nlm_write_nae_reg(nae_base, NAE_REG(block, PHY, lane_ctrl), val); 384233545Sjchandra 385233545Sjchandra if (lane_ctrl != 4) { 386233545Sjchandra rext_sel = (1 << 23); 387233545Sjchandra if (mode != PHYMODE_SGMII) 388233545Sjchandra rext_sel |= PHY_LANE_CTRL_BPC_XAUI; 389233545Sjchandra 390233545Sjchandra val = nlm_read_nae_reg(nae_base, 391233545Sjchandra NAE_REG(block, PHY, lane_ctrl)); 392233545Sjchandra val &= ~PHY_LANE_CTRL_RST; 393233545Sjchandra val |= rext_sel; 394233545Sjchandra 395233545Sjchandra /* Resetting PMA for non-zero lanes */ 396233545Sjchandra nlm_write_nae_reg(nae_base, 397233545Sjchandra NAE_REG(block, PHY, lane_ctrl), val); 398233545Sjchandra 399233545Sjchandra DELAY(20000); /* 20 ms delay, XXXJC: needed? */ 400233545Sjchandra 401233545Sjchandra val |= PHY_LANE_CTRL_RST; 402233545Sjchandra nlm_write_nae_reg(nae_base, 403233545Sjchandra NAE_REG(block, PHY, lane_ctrl), val); 404233545Sjchandra 405233545Sjchandra val = 0; 406233545Sjchandra } 407233545Sjchandra 408233545Sjchandra /* Come out of reset for TXPLL */ 409233545Sjchandra saved_data = nlm_read_nae_reg(nae_base, 410233545Sjchandra NAE_REG(block, PHY, lane_ctrl)) & 0xFFC00000; 411233545Sjchandra 412233545Sjchandra nlm_write_nae_reg(nae_base, 413233545Sjchandra NAE_REG(block, PHY, lane_ctrl), 414233545Sjchandra (0x66 << PHY_LANE_CTRL_ADDR_POS) 415233545Sjchandra | PHY_LANE_CTRL_CMD_READ 416233545Sjchandra | PHY_LANE_CTRL_CMD_START 417233545Sjchandra | PHY_LANE_CTRL_RST 418233545Sjchandra | rext_sel 419233545Sjchandra | val ); 420233545Sjchandra 421233545Sjchandra while (((val = nlm_read_nae_reg(nae_base, 422233545Sjchandra NAE_REG(block, PHY, lane_ctrl))) & 423233545Sjchandra PHY_LANE_CTRL_CMD_PENDING)); 424233545Sjchandra 425233545Sjchandra val &= 0xFF; 426233545Sjchandra /* set bit[4] to 0 */ 427233545Sjchandra val &= ~(1 << 4); 428233545Sjchandra nlm_write_nae_reg(nae_base, 429233545Sjchandra NAE_REG(block, PHY, lane_ctrl), 430233545Sjchandra (0x66 << PHY_LANE_CTRL_ADDR_POS) 431233545Sjchandra | PHY_LANE_CTRL_CMD_WRITE 432233545Sjchandra | PHY_LANE_CTRL_CMD_START 433233545Sjchandra | (0x0 << 19) /* (0x4 << 19) */ 434233545Sjchandra | rext_sel 435233545Sjchandra | saved_data 436233545Sjchandra | val ); 437233545Sjchandra 438233545Sjchandra /* re-do */ 439233545Sjchandra nlm_write_nae_reg(nae_base, 440233545Sjchandra NAE_REG(block, PHY, lane_ctrl), 441233545Sjchandra (0x66 << PHY_LANE_CTRL_ADDR_POS) 442233545Sjchandra | PHY_LANE_CTRL_CMD_WRITE 443233545Sjchandra | PHY_LANE_CTRL_CMD_START 444233545Sjchandra | (0x0 << 19) /* (0x4 << 19) */ 445233545Sjchandra | rext_sel 446233545Sjchandra | saved_data 447233545Sjchandra | val ); 448233545Sjchandra 449233545Sjchandra while (!((val = nlm_read_nae_reg(nae_base, 450233545Sjchandra NAE_REG(block, PHY, (lane_ctrl - PHY_LANE_0_CTRL)))) & 451233545Sjchandra PHY_LANE_STAT_PCR)); 452233545Sjchandra 453233545Sjchandra /* Clear the Power Down bit */ 454233545Sjchandra val = nlm_read_nae_reg(nae_base, NAE_REG(block, PHY, lane_ctrl)); 455233545Sjchandra val &= ~((1 << 29) | (0x7ffff)); 456233545Sjchandra nlm_write_nae_reg(nae_base, NAE_REG(block, PHY, lane_ctrl), 457233545Sjchandra (rext_sel | val)); 458233545Sjchandra} 459233545Sjchandra 460233545Sjchandravoid 461233545Sjchandraxlp_nae_lane_reset_txpll(uint64_t nae_base, int block, int lane_ctrl, 462233545Sjchandra int mode) 463233545Sjchandra{ 464233545Sjchandra uint32_t val = 0; 465233545Sjchandra int rext_sel = 0; 466233545Sjchandra 467233545Sjchandra if (lane_ctrl != 4) 468233545Sjchandra rext_sel = (1 << 23); 469233545Sjchandra 470233545Sjchandra val = nlm_read_nae_reg(nae_base, 471233545Sjchandra NAE_REG(block, PHY, lane_ctrl)); 472233545Sjchandra 473233545Sjchandra /* set comma bypass for XAUI */ 474233545Sjchandra if (mode != PHYMODE_SGMII) 475233545Sjchandra val |= PHY_LANE_CTRL_BPC_XAUI; 476233545Sjchandra val |= 0x100000; 477233545Sjchandra val |= (mode << PHY_LANE_CTRL_PHYMODE_POS); 478233545Sjchandra val &= ~(0x20000); 479233545Sjchandra nlm_write_nae_reg(nae_base, 480233545Sjchandra NAE_REG(block, PHY, lane_ctrl), val); 481233545Sjchandra 482233545Sjchandra val = nlm_read_nae_reg(nae_base, 483233545Sjchandra NAE_REG(block, PHY, lane_ctrl)); 484233545Sjchandra val |= 0x40000000; 485233545Sjchandra nlm_write_nae_reg(nae_base, 486233545Sjchandra NAE_REG(block, PHY, lane_ctrl), val); 487233545Sjchandra 488233545Sjchandra /* clear the power down bit */ 489233545Sjchandra val = nlm_read_nae_reg(nae_base, 490233545Sjchandra NAE_REG(block, PHY, lane_ctrl)); 491233545Sjchandra val &= ~( (1 << 29) | (0x7ffff)); 492233545Sjchandra nlm_write_nae_reg(nae_base, 493233545Sjchandra NAE_REG(block, PHY, lane_ctrl), rext_sel | val); 494233545Sjchandra} 495233545Sjchandra 496233545Sjchandravoid 497233545Sjchandraxlp_nae_config_lane_gmac(uint64_t nae_base, int cplx_mask) 498233545Sjchandra{ 499233545Sjchandra int block, lane_ctrl; 500233545Sjchandra int cplx_lane_enable; 501233545Sjchandra int lane_enable = 0; 502233545Sjchandra 503233545Sjchandra cplx_lane_enable = LM_SGMII | 504233545Sjchandra (LM_SGMII << 4) | 505233545Sjchandra (LM_SGMII << 8) | 506233545Sjchandra (LM_SGMII << 12); 507233545Sjchandra 508233545Sjchandra /* Lane mode progamming */ 509233545Sjchandra block = 7; 510233545Sjchandra 511233545Sjchandra /* Complexes 0, 1 */ 512233545Sjchandra if (cplx_mask & 0x1) 513233545Sjchandra lane_enable |= cplx_lane_enable; 514233545Sjchandra 515233545Sjchandra if (cplx_mask & 0x2) 516233545Sjchandra lane_enable |= (cplx_lane_enable << 16); 517233545Sjchandra 518233545Sjchandra if (lane_enable) { 519233545Sjchandra nlm_write_nae_reg(nae_base, 520233545Sjchandra NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_0_1), 521233545Sjchandra lane_enable); 522233545Sjchandra lane_enable = 0; 523233545Sjchandra } 524233545Sjchandra /* Complexes 2 3 */ 525233545Sjchandra if (cplx_mask & 0x4) 526233545Sjchandra lane_enable |= cplx_lane_enable; 527233545Sjchandra 528233545Sjchandra if (cplx_mask & 0x8) 529233545Sjchandra lane_enable |= (cplx_lane_enable << 16); 530233545Sjchandra 531233545Sjchandra nlm_write_nae_reg(nae_base, 532233545Sjchandra NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_2_3), 533233545Sjchandra lane_enable); 534233545Sjchandra 535233545Sjchandra /* complex 4 */ 536233545Sjchandra /* XXXJC : fix duplicate code */ 537233545Sjchandra if (cplx_mask & 0x10) { 538233545Sjchandra nlm_write_nae_reg(nae_base, 539233545Sjchandra NAE_REG(block, LANE_CFG, LANE_CFG_CPLX_4), 540233545Sjchandra ((LM_SGMII << 4) | LM_SGMII)); 541233545Sjchandra for (lane_ctrl = PHY_LANE_0_CTRL; 542233545Sjchandra lane_ctrl <= PHY_LANE_1_CTRL; lane_ctrl++) { 543233545Sjchandra if (!nlm_is_xlp8xx_ax()) 544233545Sjchandra xlp_nae_lane_reset_txpll(nae_base, 545233545Sjchandra 4, lane_ctrl, PHYMODE_SGMII); 546233545Sjchandra else 547233545Sjchandra xlp_ax_nae_lane_reset_txpll(nae_base, 4, 548233545Sjchandra lane_ctrl, PHYMODE_SGMII); 549233545Sjchandra } 550233545Sjchandra } 551233545Sjchandra 552233545Sjchandra for (block = 0; block < 4; block++) { 553233545Sjchandra if ((cplx_mask & (1 << block)) == 0) 554233545Sjchandra continue; 555233545Sjchandra 556233545Sjchandra for (lane_ctrl = PHY_LANE_0_CTRL; 557233545Sjchandra lane_ctrl <= PHY_LANE_3_CTRL; lane_ctrl++) { 558233545Sjchandra if (!nlm_is_xlp8xx_ax()) 559233545Sjchandra xlp_nae_lane_reset_txpll(nae_base, 560233545Sjchandra block, lane_ctrl, PHYMODE_SGMII); 561233545Sjchandra else 562233545Sjchandra xlp_ax_nae_lane_reset_txpll(nae_base, block, 563233545Sjchandra lane_ctrl, PHYMODE_SGMII); 564233545Sjchandra } 565233545Sjchandra } 566233545Sjchandra} 567233545Sjchandra 568233545Sjchandravoid 569233545Sjchandraconfig_egress_fifo_carvings(uint64_t nae_base, int hwport, int start_ctxt, 570233545Sjchandra int num_ctxts, int max_ctxts, struct nae_port_config *cfg) 571233545Sjchandra{ 572233545Sjchandra static uint32_t cur_start[6] = {0, 0, 0, 0, 0, 0}; 573233545Sjchandra uint32_t data = 0; 574233545Sjchandra uint32_t start = 0, size, offset; 575233545Sjchandra int i, limit; 576233545Sjchandra 577233545Sjchandra limit = start_ctxt + num_ctxts; 578233545Sjchandra /* Stage 2 FIFO */ 579233545Sjchandra start = cur_start[0]; 580233545Sjchandra for (i = start_ctxt; i < limit; i++) { 581233545Sjchandra size = cfg[hwport].stg2_fifo_size / max_ctxts; 582233545Sjchandra if (size) 583233545Sjchandra offset = size - 1; 584233545Sjchandra else 585233545Sjchandra offset = size; 586233545Sjchandra if (offset > cfg[hwport].max_stg2_offset) 587233545Sjchandra offset = cfg[hwport].max_stg2_offset; 588233545Sjchandra data = offset << 23 | 589233545Sjchandra start << 11 | 590233545Sjchandra i << 1 | 591233545Sjchandra 1; 592233545Sjchandra nlm_write_nae_reg(nae_base, NAE_STG2_PMEM_PROG, data); 593233545Sjchandra start += size; 594233545Sjchandra } 595233545Sjchandra cur_start[0] = start; 596233545Sjchandra 597233545Sjchandra /* EH FIFO */ 598233545Sjchandra start = cur_start[1]; 599233545Sjchandra for (i = start_ctxt; i < limit; i++) { 600233545Sjchandra size = cfg[hwport].eh_fifo_size / max_ctxts; 601233545Sjchandra if (size) 602233545Sjchandra offset = size - 1; 603233545Sjchandra else 604233545Sjchandra offset = size ; 605233545Sjchandra if (offset > cfg[hwport].max_eh_offset) 606233545Sjchandra offset = cfg[hwport].max_eh_offset; 607233545Sjchandra data = offset << 23 | 608233545Sjchandra start << 11 | 609233545Sjchandra i << 1 | 610233545Sjchandra 1; 611233545Sjchandra nlm_write_nae_reg(nae_base, NAE_EH_PMEM_PROG, data); 612233545Sjchandra start += size; 613233545Sjchandra } 614233545Sjchandra cur_start[1] = start; 615233545Sjchandra 616233545Sjchandra /* FROUT FIFO */ 617233545Sjchandra start = cur_start[2]; 618233545Sjchandra for (i = start_ctxt; i < limit; i++) { 619233545Sjchandra size = cfg[hwport].frout_fifo_size / max_ctxts; 620233545Sjchandra if (size) 621233545Sjchandra offset = size - 1; 622233545Sjchandra else 623233545Sjchandra offset = size ; 624233545Sjchandra if (offset > cfg[hwport].max_frout_offset) 625233545Sjchandra offset = cfg[hwport].max_frout_offset; 626233545Sjchandra data = offset << 23 | 627233545Sjchandra start << 11 | 628233545Sjchandra i << 1 | 629233545Sjchandra 1; 630233545Sjchandra nlm_write_nae_reg(nae_base, NAE_FREE_PMEM_PROG, data); 631233545Sjchandra start += size; 632233545Sjchandra } 633233545Sjchandra cur_start[2] = start; 634233545Sjchandra 635233545Sjchandra /* MS FIFO */ 636233545Sjchandra start = cur_start[3]; 637233545Sjchandra for (i = start_ctxt; i < limit; i++) { 638233545Sjchandra size = cfg[hwport].ms_fifo_size / max_ctxts; 639233545Sjchandra if (size) 640233545Sjchandra offset = size - 1; 641233545Sjchandra else 642233545Sjchandra offset = size ; 643233545Sjchandra if (offset > cfg[hwport].max_ms_offset) 644233545Sjchandra offset = cfg[hwport].max_ms_offset; 645233545Sjchandra data = offset << 22 | /* FIXME in PRM */ 646233545Sjchandra start << 11 | 647233545Sjchandra i << 1 | 648233545Sjchandra 1; 649233545Sjchandra nlm_write_nae_reg(nae_base, NAE_STR_PMEM_CMD, data); 650233545Sjchandra start += size; 651233545Sjchandra } 652233545Sjchandra cur_start[3] = start; 653233545Sjchandra 654233545Sjchandra /* PKT FIFO */ 655233545Sjchandra start = cur_start[4]; 656233545Sjchandra for (i = start_ctxt; i < limit; i++) { 657233545Sjchandra size = cfg[hwport].pkt_fifo_size / max_ctxts; 658233545Sjchandra if (size) 659233545Sjchandra offset = size - 1; 660233545Sjchandra else 661233545Sjchandra offset = size ; 662233545Sjchandra if (offset > cfg[hwport].max_pmem_offset) 663233545Sjchandra offset = cfg[hwport].max_pmem_offset; 664233545Sjchandra nlm_write_nae_reg(nae_base, NAE_TX_PKT_PMEM_CMD1, offset); 665233545Sjchandra 666233545Sjchandra data = start << 11 | 667233545Sjchandra i << 1 | 668233545Sjchandra 1; 669233545Sjchandra nlm_write_nae_reg(nae_base, NAE_TX_PKT_PMEM_CMD0, data); 670233545Sjchandra start += size; 671233545Sjchandra } 672233545Sjchandra cur_start[4] = start; 673233545Sjchandra 674233545Sjchandra /* PKT LEN FIFO */ 675233545Sjchandra start = cur_start[5]; 676233545Sjchandra for (i = start_ctxt; i < limit; i++) { 677233545Sjchandra size = cfg[hwport].pktlen_fifo_size / max_ctxts; 678233545Sjchandra if (size) 679233545Sjchandra offset = size - 1; 680233545Sjchandra else 681233545Sjchandra offset = size ; 682233545Sjchandra data = offset << 22 | 683233545Sjchandra start << 11 | 684233545Sjchandra i << 1 | 685233545Sjchandra 1; 686233545Sjchandra nlm_write_nae_reg(nae_base, NAE_TX_PKTLEN_PMEM_CMD, data); 687233545Sjchandra start += size; 688233545Sjchandra } 689233545Sjchandra cur_start[5] = start; 690233545Sjchandra} 691233545Sjchandra 692233545Sjchandravoid 693233545Sjchandraconfig_egress_fifo_credits(uint64_t nae_base, int hwport, int start_ctxt, 694233545Sjchandra int num_ctxts, int max_ctxts, struct nae_port_config *cfg) 695233545Sjchandra{ 696233545Sjchandra uint32_t data, credit, max_credit; 697233545Sjchandra int i, limit; 698233545Sjchandra 699233545Sjchandra limit = start_ctxt + num_ctxts; 700233545Sjchandra /* Stage1 -> Stage2 */ 701233545Sjchandra max_credit = cfg[hwport].max_stg2_offset + 1; 702233545Sjchandra for (i = start_ctxt; i < limit; i++) { 703233545Sjchandra credit = cfg[hwport].stg1_2_credit / max_ctxts; 704233545Sjchandra if (credit > max_credit) 705233545Sjchandra credit = max_credit; 706233545Sjchandra data = credit << 16 | 707233545Sjchandra i << 4 | 708233545Sjchandra 1; 709233545Sjchandra nlm_write_nae_reg(nae_base, NAE_STG1_STG2CRDT_CMD, data); 710233545Sjchandra } 711233545Sjchandra 712233545Sjchandra /* Stage2 -> EH */ 713233545Sjchandra max_credit = cfg[hwport].max_eh_offset + 1; 714233545Sjchandra for (i = start_ctxt; i < limit; i++) { 715233545Sjchandra credit = cfg[hwport].stg2_eh_credit / max_ctxts; 716233545Sjchandra if (credit > max_credit) 717233545Sjchandra credit = max_credit; 718233545Sjchandra data = credit << 16 | 719233545Sjchandra i << 4 | 720233545Sjchandra 1; 721233545Sjchandra nlm_write_nae_reg(nae_base, NAE_STG2_EHCRDT_CMD, data); 722233545Sjchandra } 723233545Sjchandra 724233545Sjchandra /* Stage2 -> Frout */ 725233545Sjchandra max_credit = cfg[hwport].max_frout_offset + 1; 726233545Sjchandra for (i = start_ctxt; i < limit; i++) { 727233545Sjchandra credit = cfg[hwport].stg2_frout_credit / max_ctxts; 728233545Sjchandra if (credit > max_credit) 729233545Sjchandra credit = max_credit; 730233545Sjchandra data = credit << 16 | 731233545Sjchandra i << 4 | 732233545Sjchandra 1; 733233545Sjchandra nlm_write_nae_reg(nae_base, NAE_EH_FREECRDT_CMD, data); 734233545Sjchandra } 735233545Sjchandra 736233545Sjchandra /* Stage2 -> MS */ 737233545Sjchandra max_credit = cfg[hwport].max_ms_offset + 1; 738233545Sjchandra for (i = start_ctxt; i < limit; i++) { 739233545Sjchandra credit = cfg[hwport].stg2_ms_credit / max_ctxts; 740233545Sjchandra if (credit > max_credit) 741233545Sjchandra credit = max_credit; 742233545Sjchandra data = credit << 16 | 743233545Sjchandra i << 4 | 744233545Sjchandra 1; 745233545Sjchandra nlm_write_nae_reg(nae_base, NAE_STG2_STRCRDT_CMD, data); 746233545Sjchandra } 747233545Sjchandra} 748233545Sjchandra 749233545Sjchandravoid 750233545Sjchandranlm_config_freein_fifo_uniq_cfg(uint64_t nae_base, int port, 751233545Sjchandra int nblock_free_desc) 752233545Sjchandra{ 753233545Sjchandra uint32_t val; 754233545Sjchandra int size_in_clines; 755233545Sjchandra 756233545Sjchandra size_in_clines = (nblock_free_desc / NAE_CACHELINE_SIZE); 757233545Sjchandra val = (size_in_clines << 8) | (port & 0x1f); 758233545Sjchandra nlm_write_nae_reg(nae_base, NAE_FREEIN_FIFO_UNIQ_SZ_CFG, val); 759233545Sjchandra} 760233545Sjchandra 761233545Sjchandra/* XXXJC: redundant, see ucore_spray_config() */ 762233545Sjchandravoid 763233545Sjchandranlm_config_ucore_iface_mask_cfg(uint64_t nae_base, int port, 764233545Sjchandra int nblock_ucore_mask) 765233545Sjchandra{ 766233545Sjchandra uint32_t val; 767233545Sjchandra 768233545Sjchandra val = ( 0x1U << 31) | ((nblock_ucore_mask & 0xffff) << 8) | 769233545Sjchandra (port & 0x1f); 770233545Sjchandra nlm_write_nae_reg(nae_base, NAE_UCORE_IFACEMASK_CFG, val); 771233545Sjchandra} 772233545Sjchandra 773233545Sjchandraint 774233545Sjchandranlm_nae_init_netior(uint64_t nae_base, int nblocks) 775233545Sjchandra{ 776233545Sjchandra uint32_t ctrl1, ctrl2, ctrl3; 777233545Sjchandra 778233545Sjchandra if (nblocks == 5) 779233545Sjchandra ctrl3 = 0x07 << 18; 780233545Sjchandra else 781233545Sjchandra ctrl3 = 0; 782233545Sjchandra 783233545Sjchandra switch (nblocks) { 784233545Sjchandra case 2: 785233545Sjchandra ctrl1 = 0xff; 786233545Sjchandra ctrl2 = 0x0707; 787233545Sjchandra break; 788233545Sjchandra case 4: 789233545Sjchandra case 5: 790233545Sjchandra ctrl1 = 0xfffff; 791233545Sjchandra ctrl2 = 0x07070707; 792233545Sjchandra break; 793233545Sjchandra default: 794233545Sjchandra printf("WARNING: unsupported blocks %d\n", nblocks); 795233545Sjchandra return (-1); 796233545Sjchandra } 797233545Sjchandra 798233545Sjchandra nlm_write_nae_reg(nae_base, NAE_LANE_CFG_SOFTRESET, 0); 799233545Sjchandra nlm_write_nae_reg(nae_base, NAE_NETIOR_MISC_CTRL3, ctrl3); 800233545Sjchandra nlm_write_nae_reg(nae_base, NAE_NETIOR_MISC_CTRL2, ctrl2); 801233545Sjchandra nlm_write_nae_reg(nae_base, NAE_NETIOR_MISC_CTRL1, ctrl1); 802233545Sjchandra nlm_write_nae_reg(nae_base, NAE_NETIOR_MISC_CTRL1, 0x0); 803233545Sjchandra return (0); 804233545Sjchandra} 805233545Sjchandra 806233545Sjchandravoid 807233545Sjchandranlm_nae_init_ingress(uint64_t nae_base, uint32_t desc_size) 808233545Sjchandra{ 809233545Sjchandra uint32_t rx_cfg; 810233545Sjchandra uint32_t parser_threshold = 384; 811233545Sjchandra 812233545Sjchandra rx_cfg = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG); 813233545Sjchandra rx_cfg &= ~(0x3 << 1); /* reset max message size */ 814233545Sjchandra rx_cfg &= ~(0xff << 4); /* clear freein desc cluster size */ 815233545Sjchandra rx_cfg &= ~(0x3f << 24); /* reset rx status mask */ /*XXX: why not 7f */ 816233545Sjchandra 817233545Sjchandra rx_cfg |= 1; /* rx enable */ 818233545Sjchandra rx_cfg |= (0x0 << 1); /* max message size */ 819233545Sjchandra rx_cfg |= (0x43 & 0x7f) << 24; /* rx status mask */ 820233545Sjchandra rx_cfg |= ((desc_size / 64) & 0xff) << 4; /* freein desc cluster size */ 821233545Sjchandra nlm_write_nae_reg(nae_base, NAE_RX_CONFIG, rx_cfg); 822233545Sjchandra nlm_write_nae_reg(nae_base, NAE_PARSER_CONFIG, 823233545Sjchandra (parser_threshold & 0x3ff) | 824233545Sjchandra (((parser_threshold / desc_size) + 1) & 0xff) << 12 | 825233545Sjchandra (((parser_threshold / 64) % desc_size) & 0xff) << 20); 826233545Sjchandra 827233545Sjchandra /*nlm_write_nae_reg(nae_base, NAE_RX_FREE_FIFO_THRESH, 33);*/ 828233545Sjchandra} 829233545Sjchandra 830233545Sjchandravoid 831233545Sjchandranlm_nae_init_egress(uint64_t nae_base) 832233545Sjchandra{ 833233545Sjchandra uint32_t tx_cfg; 834233545Sjchandra 835233545Sjchandra tx_cfg = nlm_read_nae_reg(nae_base, NAE_TX_CONFIG); 836233545Sjchandra if (!nlm_is_xlp8xx_ax()) { 837233545Sjchandra nlm_write_nae_reg(nae_base, NAE_TX_CONFIG, 838233545Sjchandra tx_cfg | 839233545Sjchandra 0x1 | /* tx enable */ 840233545Sjchandra 0x2 | /* tx ace */ 841233545Sjchandra 0x4 | /* tx compatible */ 842233545Sjchandra (1 << 3)); 843233545Sjchandra } else { 844233545Sjchandra nlm_write_nae_reg(nae_base, NAE_TX_CONFIG, 845233545Sjchandra tx_cfg | 846233545Sjchandra 0x1 | /* tx enable */ 847233545Sjchandra 0x2); /* tx ace */ 848233545Sjchandra } 849233545Sjchandra} 850233545Sjchandra 851233545Sjchandrauint32_t 852233545Sjchandraucore_spray_config(uint32_t interface, uint32_t ucore_mask, int cmd) 853233545Sjchandra{ 854233545Sjchandra return ((cmd & 0x1) << 31) | ((ucore_mask & 0xffff) << 8) | 855233545Sjchandra (interface & 0x1f); 856233545Sjchandra} 857233545Sjchandra 858233545Sjchandravoid 859233545Sjchandranlm_nae_init_ucore(uint64_t nae_base, int if_num, u_int ucore_mask) 860233545Sjchandra{ 861233545Sjchandra uint32_t ucfg; 862233545Sjchandra 863233545Sjchandra ucfg = ucore_spray_config(if_num, ucore_mask, 1); /* 1 : write */ 864233545Sjchandra nlm_write_nae_reg(nae_base, NAE_UCORE_IFACEMASK_CFG, ucfg); 865233545Sjchandra} 866233545Sjchandra 867233545Sjchandrauint64_t 868233545Sjchandranae_tx_desc(u_int type, u_int rdex, u_int fbid, u_int len, uint64_t addr) 869233545Sjchandra{ 870233545Sjchandra return ((uint64_t)type << 62) | 871233545Sjchandra ((uint64_t)rdex << 61) | 872233545Sjchandra ((uint64_t)fbid << 54) | 873233545Sjchandra ((uint64_t)len << 40) | addr; 874233545Sjchandra} 875233545Sjchandra 876233545Sjchandravoid 877233545Sjchandranlm_setup_l2type(uint64_t nae_base, int hwport, uint32_t l2extlen, 878233545Sjchandra uint32_t l2extoff, uint32_t extra_hdrsize, uint32_t proto_offset, 879233545Sjchandra uint32_t fixed_hdroff, uint32_t l2proto) 880233545Sjchandra{ 881233545Sjchandra uint32_t val; 882233545Sjchandra 883233545Sjchandra val = ((l2extlen & 0x3f) << 26) | 884233545Sjchandra ((l2extoff & 0x3f) << 20) | 885233545Sjchandra ((extra_hdrsize & 0x3f) << 14) | 886233545Sjchandra ((proto_offset & 0x3f) << 8) | 887233545Sjchandra ((fixed_hdroff & 0x3f) << 2) | 888233545Sjchandra (l2proto & 0x3); 889233545Sjchandra nlm_write_nae_reg(nae_base, (NAE_L2_TYPE_PORT0 + hwport), val); 890233545Sjchandra} 891233545Sjchandra 892233545Sjchandravoid 893233545Sjchandranlm_setup_l3ctable_mask(uint64_t nae_base, int hwport, uint32_t ptmask, 894233545Sjchandra uint32_t l3portmask) 895233545Sjchandra{ 896233545Sjchandra uint32_t val; 897233545Sjchandra 898233545Sjchandra val = ((ptmask & 0x1) << 6) | 899233545Sjchandra ((l3portmask & 0x1) << 5) | 900233545Sjchandra (hwport & 0x1f); 901233545Sjchandra nlm_write_nae_reg(nae_base, NAE_L3_CTABLE_MASK0, val); 902233545Sjchandra} 903233545Sjchandra 904233545Sjchandravoid 905233545Sjchandranlm_setup_l3ctable_even(uint64_t nae_base, int entry, uint32_t l3hdroff, 906233545Sjchandra uint32_t ipcsum_en, uint32_t l4protooff, 907233545Sjchandra uint32_t l2proto, uint32_t eth_type) 908233545Sjchandra{ 909233545Sjchandra uint32_t val; 910233545Sjchandra 911233545Sjchandra val = ((l3hdroff & 0x3f) << 26) | 912233545Sjchandra ((l4protooff & 0x3f) << 20) | 913233545Sjchandra ((ipcsum_en & 0x1) << 18) | 914233545Sjchandra ((l2proto & 0x3) << 16) | 915233545Sjchandra (eth_type & 0xffff); 916233545Sjchandra nlm_write_nae_reg(nae_base, (NAE_L3CTABLE0 + (entry * 2)), val); 917233545Sjchandra} 918233545Sjchandra 919233545Sjchandravoid 920233545Sjchandranlm_setup_l3ctable_odd(uint64_t nae_base, int entry, uint32_t l3off0, 921233545Sjchandra uint32_t l3len0, uint32_t l3off1, uint32_t l3len1, 922233545Sjchandra uint32_t l3off2, uint32_t l3len2) 923233545Sjchandra{ 924233545Sjchandra uint32_t val; 925233545Sjchandra 926233545Sjchandra val = ((l3off0 & 0x3f) << 26) | 927233545Sjchandra ((l3len0 & 0x1f) << 21) | 928233545Sjchandra ((l3off1 & 0x3f) << 15) | 929233545Sjchandra ((l3len1 & 0x1f) << 10) | 930233545Sjchandra ((l3off2 & 0x3f) << 4) | 931233545Sjchandra (l3len2 & 0xf); 932233545Sjchandra nlm_write_nae_reg(nae_base, (NAE_L3CTABLE0 + ((entry * 2) + 1)), val); 933233545Sjchandra} 934233545Sjchandra 935233545Sjchandravoid 936233545Sjchandranlm_setup_l4ctable_even(uint64_t nae_base, int entry, uint32_t im, 937233545Sjchandra uint32_t l3cm, uint32_t l4pm, uint32_t port, 938233545Sjchandra uint32_t l3camaddr, uint32_t l4proto) 939233545Sjchandra{ 940233545Sjchandra uint32_t val; 941233545Sjchandra 942233545Sjchandra val = ((im & 0x1) << 19) | 943233545Sjchandra ((l3cm & 0x1) << 18) | 944233545Sjchandra ((l4pm & 0x1) << 17) | 945233545Sjchandra ((port & 0x1f) << 12) | 946233545Sjchandra ((l3camaddr & 0xf) << 8) | 947233545Sjchandra (l4proto & 0xff); 948233545Sjchandra nlm_write_nae_reg(nae_base, (NAE_L4CTABLE0 + (entry * 2)), val); 949233545Sjchandra} 950233545Sjchandra 951233545Sjchandravoid 952233545Sjchandranlm_setup_l4ctable_odd(uint64_t nae_base, int entry, uint32_t l4off0, 953233545Sjchandra uint32_t l4len0, uint32_t l4off1, uint32_t l4len1) 954233545Sjchandra{ 955233545Sjchandra uint32_t val; 956233545Sjchandra 957233545Sjchandra val = ((l4off0 & 0x3f) << 21) | 958233545Sjchandra ((l4len0 & 0xf) << 17) | 959233545Sjchandra ((l4off1 & 0x3f) << 11) | 960233545Sjchandra (l4len1 & 0xf); 961233545Sjchandra nlm_write_nae_reg(nae_base, (NAE_L4CTABLE0 + ((entry * 2) + 1)), val); 962233545Sjchandra} 963233545Sjchandra 964233545Sjchandravoid 965233545Sjchandranlm_enable_hardware_parser(uint64_t nae_base) 966233545Sjchandra{ 967233545Sjchandra uint32_t val; 968233545Sjchandra 969233545Sjchandra val = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG); 970233545Sjchandra val |= (1 << 12); /* hardware parser enable */ 971233545Sjchandra nlm_write_nae_reg(nae_base, NAE_RX_CONFIG, val); 972233545Sjchandra 973233545Sjchandra /*********************************************** 974233545Sjchandra * program L3 CAM table 975233545Sjchandra ***********************************************/ 976233545Sjchandra 977233545Sjchandra /* 978233545Sjchandra * entry-0 is ipv4 MPLS type 1 label 979233545Sjchandra */ 980233545Sjchandra /* l3hdroff = 4 bytes, ether_type = 0x8847 for MPLS_type1 */ 981233545Sjchandra nlm_setup_l3ctable_even(nae_base, 0, 4, 1, 9, 1, 0x8847); 982233545Sjchandra /* l3off0 (8 bytes) -> l3len0 (1 byte) := ip proto 983233545Sjchandra * l3off1 (12 bytes) -> l3len1 (4 bytes) := src ip 984233545Sjchandra * l3off2 (16 bytes) -> l3len2 (4 bytes) := dst ip 985233545Sjchandra */ 986233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 0, 9, 1, 12, 4, 16, 4); 987233545Sjchandra 988233545Sjchandra /* 989233545Sjchandra * entry-1 is for ethernet IPv4 packets 990233545Sjchandra */ 991233545Sjchandra nlm_setup_l3ctable_even(nae_base, 1, 0, 1, 9, 1, 0x0800); 992233545Sjchandra /* l3off0 (8 bytes) -> l3len0 (1 byte) := ip proto 993233545Sjchandra * l3off1 (12 bytes) -> l3len1 (4 bytes) := src ip 994233545Sjchandra * l3off2 (16 bytes) -> l3len2 (4 bytes) := dst ip 995233545Sjchandra */ 996233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 1, 9, 1, 12, 4, 16, 4); 997233545Sjchandra 998233545Sjchandra /* 999233545Sjchandra * entry-2 is for ethernet IPv6 packets 1000233545Sjchandra */ 1001233545Sjchandra nlm_setup_l3ctable_even(nae_base, 2, 0, 1, 6, 1, 0x86dd); 1002233545Sjchandra /* l3off0 (6 bytes) -> l3len0 (1 byte) := next header (ip proto) 1003233545Sjchandra * l3off1 (8 bytes) -> l3len1 (16 bytes) := src ip 1004233545Sjchandra * l3off2 (24 bytes) -> l3len2 (16 bytes) := dst ip 1005233545Sjchandra */ 1006233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 2, 6, 1, 8, 16, 24, 16); 1007233545Sjchandra 1008233545Sjchandra /* 1009233545Sjchandra * entry-3 is for ethernet ARP packets 1010233545Sjchandra */ 1011233545Sjchandra nlm_setup_l3ctable_even(nae_base, 3, 0, 0, 9, 1, 0x0806); 1012233545Sjchandra /* extract 30 bytes from packet start */ 1013233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 3, 0, 30, 0, 0, 0, 0); 1014233545Sjchandra 1015233545Sjchandra /* 1016233545Sjchandra * entry-4 is for ethernet FCoE packets 1017233545Sjchandra */ 1018233545Sjchandra nlm_setup_l3ctable_even(nae_base, 4, 0, 0, 9, 1, 0x8906); 1019233545Sjchandra /* FCoE packet consists of 4 byte start-of-frame, 1020233545Sjchandra * and 24 bytes of frame header, followed by 1021233545Sjchandra * 64 bytes of optional-header (ESP, network..), 1022233545Sjchandra * 2048 bytes of payload, 36 bytes of optional 1023233545Sjchandra * "fill bytes" or ESP trailer, 4 bytes of CRC, 1024233545Sjchandra * and 4 bytes of end-of-frame 1025233545Sjchandra * We extract the first 4 + 24 = 28 bytes 1026233545Sjchandra */ 1027233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 4, 0, 28, 0, 0, 0, 0); 1028233545Sjchandra 1029233545Sjchandra /* 1030233545Sjchandra * entry-5 is for vlan tagged frames (0x8100) 1031233545Sjchandra */ 1032233545Sjchandra nlm_setup_l3ctable_even(nae_base, 5, 0, 0, 9, 1, 0x8100); 1033233545Sjchandra /* we extract 31 bytes from the payload */ 1034233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 5, 0, 31, 0, 0, 0, 0); 1035233545Sjchandra 1036233545Sjchandra /* 1037233545Sjchandra * entry-6 is for ieee 802.1ad provider bridging 1038233545Sjchandra * tagged frames (0x88a8) 1039233545Sjchandra */ 1040233545Sjchandra nlm_setup_l3ctable_even(nae_base, 6, 0, 0, 9, 1, 0x88a8); 1041233545Sjchandra /* we extract 31 bytes from the payload */ 1042233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 6, 0, 31, 0, 0, 0, 0); 1043233545Sjchandra 1044233545Sjchandra /* 1045233545Sjchandra * entry-7 is for Cisco's Q-in-Q tagged frames (0x9100) 1046233545Sjchandra */ 1047233545Sjchandra nlm_setup_l3ctable_even(nae_base, 7, 0, 0, 9, 1, 0x9100); 1048233545Sjchandra /* we extract 31 bytes from the payload */ 1049233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 7, 0, 31, 0, 0, 0, 0); 1050233545Sjchandra 1051233545Sjchandra /* 1052233545Sjchandra * entry-8 is for Ethernet Jumbo frames (0x8870) 1053233545Sjchandra */ 1054233545Sjchandra nlm_setup_l3ctable_even(nae_base, 8, 0, 0, 9, 1, 0x8870); 1055233545Sjchandra /* we extract 31 bytes from the payload */ 1056233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 8, 0, 31, 0, 0, 0, 0); 1057233545Sjchandra 1058233545Sjchandra /* 1059233545Sjchandra * entry-9 is for MPLS Multicast frames (0x8848) 1060233545Sjchandra */ 1061233545Sjchandra nlm_setup_l3ctable_even(nae_base, 9, 0, 0, 9, 1, 0x8848); 1062233545Sjchandra /* we extract 31 bytes from the payload */ 1063233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 9, 0, 31, 0, 0, 0, 0); 1064233545Sjchandra 1065233545Sjchandra /* 1066233545Sjchandra * entry-10 is for IEEE 802.1ae MAC Security frames (0x88e5) 1067233545Sjchandra */ 1068233545Sjchandra nlm_setup_l3ctable_even(nae_base, 10, 0, 0, 9, 1, 0x88e5); 1069233545Sjchandra /* we extract 31 bytes from the payload */ 1070233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 10, 0, 31, 0, 0, 0, 0); 1071233545Sjchandra 1072233545Sjchandra /* 1073233545Sjchandra * entry-11 is for PTP frames (0x88f7) 1074233545Sjchandra */ 1075233545Sjchandra nlm_setup_l3ctable_even(nae_base, 11, 0, 0, 9, 1, 0x88f7); 1076233545Sjchandra /* PTP messages can be sent as UDP messages over 1077233545Sjchandra * IPv4 or IPv6; and as a raw ethernet message 1078233545Sjchandra * with ethertype 0x88f7. The message contents 1079233545Sjchandra * are the same for UDP or ethernet based encapsulations 1080233545Sjchandra * The header is 34 bytes long, and we extract 1081233545Sjchandra * it all out. 1082233545Sjchandra */ 1083233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 11, 0, 31, 31, 2, 0, 0); 1084233545Sjchandra 1085233545Sjchandra /* 1086233545Sjchandra * entry-12 is for ethernet Link Control Protocol (LCP) 1087233545Sjchandra * used with PPPoE 1088233545Sjchandra */ 1089233545Sjchandra nlm_setup_l3ctable_even(nae_base, 12, 0, 0, 9, 1, 0xc021); 1090233545Sjchandra /* LCP packet consists of 1 byte of code, 1 byte of 1091233545Sjchandra * identifier and two bytes of length followed by 1092233545Sjchandra * data (upto length bytes). 1093233545Sjchandra * We extract 4 bytes from start of packet 1094233545Sjchandra */ 1095233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 12, 0, 4, 0, 0, 0, 0); 1096233545Sjchandra 1097233545Sjchandra /* 1098233545Sjchandra * entry-13 is for ethernet Link Quality Report (0xc025) 1099233545Sjchandra * used with PPPoE 1100233545Sjchandra */ 1101233545Sjchandra nlm_setup_l3ctable_even(nae_base, 13, 0, 0, 9, 1, 0xc025); 1102233545Sjchandra /* We extract 31 bytes from packet start */ 1103233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 13, 0, 31, 0, 0, 0, 0); 1104233545Sjchandra 1105233545Sjchandra /* 1106233545Sjchandra * entry-14 is for PPPoE Session (0x8864) 1107233545Sjchandra */ 1108233545Sjchandra nlm_setup_l3ctable_even(nae_base, 14, 0, 0, 9, 1, 0x8864); 1109233545Sjchandra /* We extract 31 bytes from packet start */ 1110233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 14, 0, 31, 0, 0, 0, 0); 1111233545Sjchandra 1112233545Sjchandra /* 1113233545Sjchandra * entry-15 - default entry 1114233545Sjchandra */ 1115233545Sjchandra nlm_setup_l3ctable_even(nae_base, 15, 0, 0, 0, 0, 0x0000); 1116233545Sjchandra /* We extract 31 bytes from packet start */ 1117233545Sjchandra nlm_setup_l3ctable_odd(nae_base, 15, 0, 31, 0, 0, 0, 0); 1118233545Sjchandra 1119233545Sjchandra /*********************************************** 1120233545Sjchandra * program L4 CAM table 1121233545Sjchandra ***********************************************/ 1122233545Sjchandra 1123233545Sjchandra /* 1124233545Sjchandra * entry-0 - tcp packets (0x6) 1125233545Sjchandra */ 1126233545Sjchandra nlm_setup_l4ctable_even(nae_base, 0, 0, 0, 1, 0, 0, 0x6); 1127233545Sjchandra /* tcp header is 20 bytes without tcp options 1128233545Sjchandra * We extract 20 bytes from tcp start */ 1129233545Sjchandra nlm_setup_l4ctable_odd(nae_base, 0, 0, 15, 15, 5); 1130233545Sjchandra 1131233545Sjchandra /* 1132233545Sjchandra * entry-1 - udp packets (0x11) 1133233545Sjchandra */ 1134233545Sjchandra nlm_setup_l4ctable_even(nae_base, 1, 0, 0, 1, 0, 0, 0x11); 1135233545Sjchandra /* udp header is 8 bytes in size. 1136233545Sjchandra * We extract 8 bytes from udp start */ 1137233545Sjchandra nlm_setup_l4ctable_odd(nae_base, 1, 0, 8, 0, 0); 1138233545Sjchandra 1139233545Sjchandra /* 1140233545Sjchandra * entry-2 - sctp packets (0x84) 1141233545Sjchandra */ 1142233545Sjchandra nlm_setup_l4ctable_even(nae_base, 2, 0, 0, 1, 0, 0, 0x84); 1143233545Sjchandra /* sctp packets have a 12 byte generic header 1144233545Sjchandra * and various chunks. 1145233545Sjchandra * We extract 12 bytes from sctp start */ 1146233545Sjchandra nlm_setup_l4ctable_odd(nae_base, 2, 0, 12, 0, 0); 1147233545Sjchandra 1148233545Sjchandra /* 1149233545Sjchandra * entry-3 - RDP packets (0x1b) 1150233545Sjchandra */ 1151233545Sjchandra nlm_setup_l4ctable_even(nae_base, 3, 0, 0, 1, 0, 0, 0x1b); 1152233545Sjchandra /* RDP packets have 18 bytes of generic header 1153233545Sjchandra * before variable header starts. 1154233545Sjchandra * We extract 18 bytes from rdp start */ 1155233545Sjchandra nlm_setup_l4ctable_odd(nae_base, 3, 0, 15, 15, 3); 1156233545Sjchandra 1157233545Sjchandra /* 1158233545Sjchandra * entry-4 - DCCP packets (0x21) 1159233545Sjchandra */ 1160233545Sjchandra nlm_setup_l4ctable_even(nae_base, 4, 0, 0, 1, 0, 0, 0x21); 1161233545Sjchandra /* DCCP has two types of generic headers of 1162233545Sjchandra * sizes 16 bytes and 12 bytes if X = 1. 1163233545Sjchandra * We extract 16 bytes from dccp start */ 1164233545Sjchandra nlm_setup_l4ctable_odd(nae_base, 4, 0, 15, 15, 1); 1165233545Sjchandra 1166233545Sjchandra /* 1167233545Sjchandra * entry-5 - ipv6 encapsulated in ipv4 packets (0x29) 1168233545Sjchandra */ 1169233545Sjchandra nlm_setup_l4ctable_even(nae_base, 5, 0, 0, 1, 0, 0, 0x29); 1170233545Sjchandra /* ipv4 header is 20 bytes excluding IP options. 1171233545Sjchandra * We extract 20 bytes from IPv4 start */ 1172233545Sjchandra nlm_setup_l4ctable_odd(nae_base, 5, 0, 15, 15, 5); 1173233545Sjchandra 1174233545Sjchandra /* 1175233545Sjchandra * entry-6 - ip in ip encapsulation packets (0x04) 1176233545Sjchandra */ 1177233545Sjchandra nlm_setup_l4ctable_even(nae_base, 6, 0, 0, 1, 0, 0, 0x04); 1178233545Sjchandra /* ipv4 header is 20 bytes excluding IP options. 1179233545Sjchandra * We extract 20 bytes from ipv4 start */ 1180233545Sjchandra nlm_setup_l4ctable_odd(nae_base, 6, 0, 15, 15, 5); 1181233545Sjchandra 1182233545Sjchandra /* 1183233545Sjchandra * entry-7 - default entry (0x0) 1184233545Sjchandra */ 1185233545Sjchandra nlm_setup_l4ctable_even(nae_base, 7, 0, 0, 1, 0, 0, 0x0); 1186233545Sjchandra /* We extract 20 bytes from packet start */ 1187233545Sjchandra nlm_setup_l4ctable_odd(nae_base, 7, 0, 15, 15, 5); 1188233545Sjchandra} 1189233545Sjchandra 1190233545Sjchandravoid 1191233545Sjchandranlm_enable_hardware_parser_per_port(uint64_t nae_base, int block, int port) 1192233545Sjchandra{ 1193233545Sjchandra int hwport = (block * 4) + (port & 0x3); 1194233545Sjchandra 1195233545Sjchandra /* program L2 and L3 header extraction for each port */ 1196233545Sjchandra /* enable ethernet L2 mode on port */ 1197233545Sjchandra nlm_setup_l2type(nae_base, hwport, 0, 0, 0, 0, 0, 1); 1198233545Sjchandra 1199233545Sjchandra /* l2proto and ethtype included in l3cam */ 1200233545Sjchandra nlm_setup_l3ctable_mask(nae_base, hwport, 1, 0); 1201233545Sjchandra} 1202233545Sjchandra 1203233545Sjchandravoid 1204233545Sjchandranlm_prepad_enable(uint64_t nae_base, int size) 1205233545Sjchandra{ 1206233545Sjchandra uint32_t val; 1207233545Sjchandra 1208233545Sjchandra val = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG); 1209233545Sjchandra val |= (1 << 13); /* prepad enable */ 1210233545Sjchandra val |= ((size & 0x3) << 22); /* prepad size */ 1211233545Sjchandra nlm_write_nae_reg(nae_base, NAE_RX_CONFIG, val); 1212233545Sjchandra} 1213233545Sjchandra 1214233545Sjchandravoid 1215233545Sjchandranlm_setup_1588_timer(uint64_t nae_base, struct nae_port_config *cfg) 1216233545Sjchandra{ 1217233545Sjchandra uint32_t hi, lo, val; 1218233545Sjchandra 1219233545Sjchandra hi = cfg[0].ieee1588_userval >> 32; 1220233545Sjchandra lo = cfg[0].ieee1588_userval & 0xffffffff; 1221233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_USER_VALUE_HI, hi); 1222233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_USER_VALUE_LO, lo); 1223233545Sjchandra 1224233545Sjchandra hi = cfg[0].ieee1588_ptpoff >> 32; 1225233545Sjchandra lo = cfg[0].ieee1588_ptpoff & 0xffffffff; 1226233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_OFFSET_HI, hi); 1227233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_OFFSET_LO, lo); 1228233545Sjchandra 1229233545Sjchandra hi = cfg[0].ieee1588_tmr1 >> 32; 1230233545Sjchandra lo = cfg[0].ieee1588_tmr1 & 0xffffffff; 1231233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR1_HI, hi); 1232233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR1_LO, lo); 1233233545Sjchandra 1234233545Sjchandra hi = cfg[0].ieee1588_tmr2 >> 32; 1235233545Sjchandra lo = cfg[0].ieee1588_tmr2 & 0xffffffff; 1236233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR2_HI, hi); 1237233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR2_LO, lo); 1238233545Sjchandra 1239233545Sjchandra hi = cfg[0].ieee1588_tmr3 >> 32; 1240233545Sjchandra lo = cfg[0].ieee1588_tmr3 & 0xffffffff; 1241233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR3_HI, hi); 1242233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_TMR3_LO, lo); 1243233545Sjchandra 1244233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_INC_INTG, 1245233545Sjchandra cfg[0].ieee1588_inc_intg); 1246233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_INC_NUM, 1247233545Sjchandra cfg[0].ieee1588_inc_num); 1248233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_INC_DEN, 1249233545Sjchandra cfg[0].ieee1588_inc_den); 1250233545Sjchandra 1251233545Sjchandra val = nlm_read_nae_reg(nae_base, NAE_1588_PTP_CONTROL); 1252233545Sjchandra /* set and clear freq_mul = 1 */ 1253233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_CONTROL, val | (0x1 << 1)); 1254233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_CONTROL, val); 1255233545Sjchandra /* set and clear load_user_val = 1 */ 1256233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_CONTROL, val | (0x1 << 6)); 1257233545Sjchandra nlm_write_nae_reg(nae_base, NAE_1588_PTP_CONTROL, val); 1258233545Sjchandra} 1259233545Sjchandra 1260233545Sjchandravoid 1261233545Sjchandranlm_mac_enable(uint64_t nae_base, int nblock, int port_type, int port) 1262233545Sjchandra{ 1263233545Sjchandra uint32_t mac_cfg1, xaui_cfg; 1264233545Sjchandra uint32_t netwk_inf; 1265233545Sjchandra int iface = port & 0x3; 1266233545Sjchandra 1267233545Sjchandra switch(port_type) { 1268233545Sjchandra case SGMIIC: 1269233545Sjchandra netwk_inf = nlm_read_nae_reg(nae_base, 1270233545Sjchandra SGMII_NET_IFACE_CTRL(nblock, iface)); 1271233545Sjchandra nlm_write_nae_reg(nae_base, 1272233545Sjchandra SGMII_NET_IFACE_CTRL(nblock, iface), 1273233545Sjchandra netwk_inf | 1274233545Sjchandra (1 << 2)); /* enable tx */ 1275233545Sjchandra mac_cfg1 = nlm_read_nae_reg(nae_base, 1276233545Sjchandra SGMII_MAC_CONF1(nblock, iface)); 1277233545Sjchandra nlm_write_nae_reg(nae_base, 1278233545Sjchandra SGMII_MAC_CONF1(nblock, iface), 1279233545Sjchandra mac_cfg1 | 1280233545Sjchandra (1 << 2) | /* rx enable */ 1281233545Sjchandra 1); /* tx enable */ 1282233545Sjchandra break; 1283233545Sjchandra case XAUIC: 1284233545Sjchandra xaui_cfg = nlm_read_nae_reg(nae_base, 1285233545Sjchandra XAUI_CONFIG1(nblock)); 1286233545Sjchandra nlm_write_nae_reg(nae_base, 1287233545Sjchandra XAUI_CONFIG1(nblock), 1288233545Sjchandra xaui_cfg | 1289233545Sjchandra XAUI_CONFIG_TFEN | 1290233545Sjchandra XAUI_CONFIG_RFEN); 1291233545Sjchandra break; 1292233545Sjchandra case ILC: 1293233545Sjchandra break; 1294233545Sjchandra } 1295233545Sjchandra} 1296233545Sjchandra 1297233545Sjchandravoid 1298233545Sjchandranlm_mac_disable(uint64_t nae_base, int nblock, int port_type, int port) 1299233545Sjchandra{ 1300233545Sjchandra uint32_t mac_cfg1, xaui_cfg; 1301233545Sjchandra uint32_t netwk_inf; 1302233545Sjchandra int iface = port & 0x3; 1303233545Sjchandra 1304233545Sjchandra switch(port_type) { 1305233545Sjchandra case SGMIIC: 1306233545Sjchandra mac_cfg1 = nlm_read_nae_reg(nae_base, 1307233545Sjchandra SGMII_MAC_CONF1(nblock, iface)); 1308233545Sjchandra nlm_write_nae_reg(nae_base, 1309233545Sjchandra SGMII_MAC_CONF1(nblock, iface), 1310233545Sjchandra mac_cfg1 & 1311233545Sjchandra ~((1 << 2) | /* rx enable */ 1312233545Sjchandra 1)); /* tx enable */ 1313233545Sjchandra netwk_inf = nlm_read_nae_reg(nae_base, 1314233545Sjchandra SGMII_NET_IFACE_CTRL(nblock, iface)); 1315233545Sjchandra nlm_write_nae_reg(nae_base, 1316233545Sjchandra SGMII_NET_IFACE_CTRL(nblock, iface), 1317233545Sjchandra netwk_inf & 1318233545Sjchandra ~(1 << 2)); /* enable tx */ 1319233545Sjchandra break; 1320233545Sjchandra case XAUIC: 1321233545Sjchandra xaui_cfg = nlm_read_nae_reg(nae_base, 1322233545Sjchandra XAUI_CONFIG1(nblock)); 1323233545Sjchandra nlm_write_nae_reg(nae_base, 1324233545Sjchandra XAUI_CONFIG1(nblock), 1325233545Sjchandra xaui_cfg & 1326233545Sjchandra ~(XAUI_CONFIG_TFEN | 1327233545Sjchandra XAUI_CONFIG_RFEN)); 1328233545Sjchandra break; 1329233545Sjchandra case ILC: 1330233545Sjchandra break; 1331233545Sjchandra } 1332233545Sjchandra} 1333233545Sjchandra 1334233545Sjchandra/* 1335233545Sjchandra * Set IOR credits for the ports in ifmask to valmask 1336233545Sjchandra */ 1337233545Sjchandrastatic void 1338233545Sjchandranlm_nae_set_ior_credit(uint64_t nae_base, uint32_t ifmask, uint32_t valmask) 1339233545Sjchandra{ 1340233545Sjchandra uint32_t tx_config, tx_ior_credit; 1341233545Sjchandra 1342233545Sjchandra tx_ior_credit = nlm_read_nae_reg(nae_base, NAE_TX_IORCRDT_INIT); 1343233545Sjchandra tx_ior_credit &= ~ifmask; 1344233545Sjchandra tx_ior_credit |= valmask; 1345233545Sjchandra nlm_write_nae_reg(nae_base, NAE_TX_IORCRDT_INIT, tx_ior_credit); 1346233545Sjchandra 1347233545Sjchandra tx_config = nlm_read_nae_reg(nae_base, NAE_TX_CONFIG); 1348233545Sjchandra /* need to toggle these bits for credits to be loaded */ 1349233545Sjchandra nlm_write_nae_reg(nae_base, NAE_TX_CONFIG, 1350233545Sjchandra tx_config | (TXINITIORCR(ifmask))); 1351233545Sjchandra nlm_write_nae_reg(nae_base, NAE_TX_CONFIG, 1352233545Sjchandra tx_config & ~(TXINITIORCR(ifmask))); 1353233545Sjchandra} 1354233545Sjchandra 1355233545Sjchandraint 1356233545Sjchandranlm_nae_open_if(uint64_t nae_base, int nblock, int port_type, 1357233545Sjchandra int port, uint32_t desc_size) 1358233545Sjchandra{ 1359233545Sjchandra uint32_t netwk_inf; 1360245880Sjchandra uint32_t mac_cfg1, netior_ctrl3; 1361245880Sjchandra int iface, iface_ctrl_reg, iface_ctrl3_reg, conf1_reg, conf2_reg; 1362233545Sjchandra 1363233545Sjchandra switch (port_type) { 1364233545Sjchandra case XAUIC: 1365233545Sjchandra netwk_inf = nlm_read_nae_reg(nae_base, 1366233545Sjchandra XAUI_NETIOR_XGMAC_CTRL1(nblock)); 1367233545Sjchandra netwk_inf |= (1 << NETIOR_XGMAC_STATS_CLR_POS); 1368233545Sjchandra nlm_write_nae_reg(nae_base, 1369233545Sjchandra XAUI_NETIOR_XGMAC_CTRL1(nblock), netwk_inf); 1370233545Sjchandra 1371233545Sjchandra nlm_nae_set_ior_credit(nae_base, 0xf << port, 0xf << port); 1372233545Sjchandra break; 1373233545Sjchandra 1374233545Sjchandra case ILC: 1375233545Sjchandra nlm_nae_set_ior_credit(nae_base, 0xff << port, 0xff << port); 1376233545Sjchandra break; 1377233545Sjchandra 1378233545Sjchandra case SGMIIC: 1379233545Sjchandra nlm_nae_set_ior_credit(nae_base, 0x1 << port, 0); 1380233545Sjchandra 1381233545Sjchandra /* 1382233545Sjchandra * XXXJC: split this and merge to sgmii.c 1383233545Sjchandra * some of this is duplicated from there. 1384233545Sjchandra */ 1385233545Sjchandra /* init phy id to access internal PCS */ 1386233545Sjchandra iface = port & 0x3; 1387233545Sjchandra iface_ctrl_reg = SGMII_NET_IFACE_CTRL(nblock, iface); 1388233545Sjchandra conf1_reg = SGMII_MAC_CONF1(nblock, iface); 1389233545Sjchandra conf2_reg = SGMII_MAC_CONF2(nblock, iface); 1390233545Sjchandra 1391233545Sjchandra netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg); 1392233545Sjchandra netwk_inf &= 0x7ffffff; 1393233545Sjchandra netwk_inf |= (port << 27); 1394233545Sjchandra nlm_write_nae_reg(nae_base, iface_ctrl_reg, netwk_inf); 1395233545Sjchandra 1396233545Sjchandra /* Sofreset sgmii port - set bit 11 to 0 */ 1397233545Sjchandra netwk_inf &= 0xfffff7ff; 1398233545Sjchandra nlm_write_nae_reg(nae_base, iface_ctrl_reg, netwk_inf); 1399233545Sjchandra 1400233545Sjchandra /* Reset Gmac */ 1401233545Sjchandra mac_cfg1 = nlm_read_nae_reg(nae_base, conf1_reg); 1402233545Sjchandra nlm_write_nae_reg(nae_base, conf1_reg, 1403233545Sjchandra mac_cfg1 | 1404261455Seadler (1U << 31) | /* soft reset */ 1405233545Sjchandra (1 << 2) | /* rx enable */ 1406233545Sjchandra (1)); /* tx enable */ 1407233545Sjchandra 1408233545Sjchandra /* default to 1G */ 1409233545Sjchandra nlm_write_nae_reg(nae_base, 1410233545Sjchandra conf2_reg, 1411233545Sjchandra (0x7 << 12) | /* interface preamble length */ 1412233545Sjchandra (0x2 << 8) | /* interface mode */ 1413233545Sjchandra (0x1 << 2) | /* pad crc enable */ 1414233545Sjchandra (0x1)); /* full duplex */ 1415233545Sjchandra 1416233545Sjchandra /* clear gmac reset */ 1417233545Sjchandra mac_cfg1 = nlm_read_nae_reg(nae_base, conf1_reg); 1418261455Seadler nlm_write_nae_reg(nae_base, conf1_reg, mac_cfg1 & ~(1U << 31)); 1419245880Sjchandra 1420233545Sjchandra /* clear speed debug bit */ 1421233545Sjchandra iface_ctrl3_reg = SGMII_NET_IFACE_CTRL3(nblock, iface); 1422233545Sjchandra netior_ctrl3 = nlm_read_nae_reg(nae_base, iface_ctrl3_reg); 1423233545Sjchandra nlm_write_nae_reg(nae_base, iface_ctrl3_reg, 1424233545Sjchandra netior_ctrl3 & ~(1 << 6)); 1425233545Sjchandra 1426233545Sjchandra /* disable TX, RX for now */ 1427233545Sjchandra mac_cfg1 = nlm_read_nae_reg(nae_base, conf1_reg); 1428233545Sjchandra nlm_write_nae_reg(nae_base, conf1_reg, mac_cfg1 & ~(0x5)); 1429233545Sjchandra netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg); 1430233545Sjchandra nlm_write_nae_reg(nae_base, iface_ctrl_reg, 1431233545Sjchandra netwk_inf & ~(0x1 << 2)); 1432233545Sjchandra 1433233545Sjchandra /* clear stats counters */ 1434233545Sjchandra netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg); 1435233545Sjchandra nlm_write_nae_reg(nae_base, iface_ctrl_reg, 1436233545Sjchandra netwk_inf | (1 << 15)); 1437245880Sjchandra 1438233545Sjchandra /* enable stats counters */ 1439233545Sjchandra netwk_inf = nlm_read_nae_reg(nae_base, iface_ctrl_reg); 1440233545Sjchandra nlm_write_nae_reg(nae_base, iface_ctrl_reg, 1441233545Sjchandra (netwk_inf & ~(1 << 15)) | (1 << 16)); 1442245880Sjchandra 1443245880Sjchandra /* flow control? */ 1444233545Sjchandra mac_cfg1 = nlm_read_nae_reg(nae_base, conf1_reg); 1445233545Sjchandra nlm_write_nae_reg(nae_base, conf1_reg, 1446233545Sjchandra mac_cfg1 | (0x3 << 4)); 1447245880Sjchandra break; 1448233545Sjchandra } 1449233545Sjchandra 1450233545Sjchandra nlm_nae_init_ingress(nae_base, desc_size); 1451233545Sjchandra nlm_nae_init_egress(nae_base); 1452233545Sjchandra 1453233545Sjchandra return (0); 1454233545Sjchandra} 1455