1 /* $OpenBSD: if_mvpp.c,v 1.53 2024/05/13 01:15:50 jsg Exp $ */ 2 /* 3 * Copyright (c) 2008, 2019 Mark Kettenis <kettenis@openbsd.org> 4 * Copyright (c) 2017, 2020 Patrick Wildt <patrick@blueri.se> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 /* 19 * Copyright (C) 2016 Marvell International Ltd. 20 * 21 * Marvell BSD License Option 22 * 23 * If you received this File from Marvell, you may opt to use, redistribute 24 * and/or modify this File under the following licensing terms. 25 * Redistribution and use in source and binary forms, with or without 26 * modification, are permitted provided that the following conditions are met: 27 * 28 * * Redistributions of source code must retain the above copyright notice, 29 * this list of conditions and the following disclaimer. 30 * 31 * * Redistributions in binary form must reproduce the above copyright 32 * notice, this list of conditions and the following disclaimer in the 33 * documentation and/or other materials provided with the distribution. 34 * 35 * * Neither the name of Marvell nor the names of its contributors may be 36 * used to endorse or promote products derived from this software without 37 * specific prior written permission. 38 * 39 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 40 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 42 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 43 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 44 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 45 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 46 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 47 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 48 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 49 * POSSIBILITY OF SUCH DAMAGE. 50 */ 51 52 #include "bpfilter.h" 53 54 #include <sys/param.h> 55 #include <sys/systm.h> 56 #include <sys/device.h> 57 #include <sys/kernel.h> 58 #include <sys/malloc.h> 59 #include <sys/mbuf.h> 60 #include <sys/queue.h> 61 #include <sys/socket.h> 62 #include <sys/sockio.h> 63 #include <sys/timeout.h> 64 65 #include <uvm/uvm_extern.h> 66 67 #include <machine/cpufunc.h> 68 #include <machine/bus.h> 69 #include <machine/fdt.h> 70 71 #include <net/if.h> 72 #include <net/if_media.h> 73 #include <net/ppp_defs.h> 74 75 #include <dev/ofw/openfirm.h> 76 #include <dev/ofw/ofw_clock.h> 77 #include <dev/ofw/ofw_gpio.h> 78 #include <dev/ofw/ofw_misc.h> 79 #include <dev/ofw/ofw_pinctrl.h> 80 #include <dev/ofw/ofw_regulator.h> 81 #include <dev/ofw/fdt.h> 82 83 #include <dev/mii/mii.h> 84 #include <dev/mii/miivar.h> 85 86 #if NBPFILTER > 0 87 #include <net/bpf.h> 88 #endif 89 90 #include <netinet/in.h> 91 #include <netinet/ip.h> 92 #include <netinet/if_ether.h> 93 94 #include <netinet6/in6_var.h> 95 #include <netinet/ip6.h> 96 97 #include <dev/fdt/if_mvppreg.h> 98 99 struct mvpp2_buf { 100 bus_dmamap_t mb_map; 101 struct mbuf *mb_m; 102 }; 103 104 #define MVPP2_NTXDESC 512 105 #define MVPP2_NTXSEGS 16 106 #define MVPP2_NRXDESC 512 107 108 struct mvpp2_bm_pool { 109 struct mvpp2_dmamem *bm_mem; 110 struct mvpp2_buf *rxbuf; 111 uint32_t *freelist; 112 int free_prod; 113 int free_cons; 114 }; 115 116 #define MVPP2_BM_SIZE 64 117 #define MVPP2_BM_POOL_PTR_ALIGN 128 118 #define MVPP2_BM_POOLS_NUM 8 119 #define MVPP2_BM_ALIGN 32 120 121 struct mvpp2_tx_queue { 122 uint8_t id; 123 uint8_t log_id; 124 struct mvpp2_dmamem *ring; 125 struct mvpp2_buf *buf; 126 struct mvpp2_tx_desc *descs; 127 int prod; 128 int cons; 129 130 uint32_t done_pkts_coal; 131 }; 132 133 struct mvpp2_rx_queue { 134 uint8_t id; 135 struct mvpp2_dmamem *ring; 136 struct mvpp2_rx_desc *descs; 137 int prod; 138 struct if_rxring rxring; 139 int cons; 140 141 uint32_t pkts_coal; 142 uint32_t time_coal; 143 }; 144 145 struct mvpp2_dmamem { 146 bus_dmamap_t mdm_map; 147 bus_dma_segment_t mdm_seg; 148 size_t mdm_size; 149 caddr_t mdm_kva; 150 }; 151 #define MVPP2_DMA_MAP(_mdm) ((_mdm)->mdm_map) 152 #define MVPP2_DMA_LEN(_mdm) ((_mdm)->mdm_size) 153 #define MVPP2_DMA_DVA(_mdm) ((_mdm)->mdm_map->dm_segs[0].ds_addr) 154 #define MVPP2_DMA_KVA(_mdm) ((void *)(_mdm)->mdm_kva) 155 156 struct mvpp2_port; 157 struct mvpp2_softc { 158 struct device sc_dev; 159 int sc_node; 160 bus_space_tag_t sc_iot; 161 bus_space_handle_t sc_ioh_base; 162 bus_space_handle_t sc_ioh_iface; 163 paddr_t sc_ioh_paddr; 164 bus_size_t sc_iosize_base; 165 bus_size_t sc_iosize_iface; 166 bus_dma_tag_t sc_dmat; 167 struct regmap *sc_rm; 168 169 uint32_t sc_tclk; 170 171 struct mvpp2_bm_pool *sc_bm_pools; 172 int sc_npools; 173 174 struct mvpp2_prs_shadow *sc_prs_shadow; 175 uint8_t *sc_prs_double_vlans; 176 177 int sc_aggr_ntxq; 178 struct mvpp2_tx_queue *sc_aggr_txqs; 179 180 struct mvpp2_port **sc_ports; 181 }; 182 183 struct mvpp2_port { 184 struct device sc_dev; 185 struct mvpp2_softc *sc; 186 int sc_node; 187 bus_dma_tag_t sc_dmat; 188 int sc_id; 189 int sc_gop_id; 190 191 struct arpcom sc_ac; 192 #define sc_lladdr sc_ac.ac_enaddr 193 struct mii_data sc_mii; 194 #define sc_media sc_mii.mii_media 195 struct mii_bus *sc_mdio; 196 197 enum { 198 PHY_MODE_XAUI, 199 PHY_MODE_10GBASER, 200 PHY_MODE_2500BASEX, 201 PHY_MODE_1000BASEX, 202 PHY_MODE_SGMII, 203 PHY_MODE_RGMII, 204 PHY_MODE_RGMII_ID, 205 PHY_MODE_RGMII_RXID, 206 PHY_MODE_RGMII_TXID, 207 } sc_phy_mode; 208 int sc_fixed_link; 209 int sc_inband_status; 210 int sc_link; 211 int sc_phyloc; 212 int sc_sfp; 213 214 int sc_ntxq; 215 int sc_nrxq; 216 217 struct mvpp2_tx_queue *sc_txqs; 218 struct mvpp2_rx_queue *sc_rxqs; 219 220 struct timeout sc_tick; 221 222 uint32_t sc_tx_time_coal; 223 }; 224 225 #define MVPP2_MAX_PORTS 4 226 227 struct mvpp2_attach_args { 228 int ma_node; 229 bus_dma_tag_t ma_dmat; 230 }; 231 232 #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) 233 234 static struct rwlock mvpp2_sff_lock = RWLOCK_INITIALIZER("mvpp2sff"); 235 236 int mvpp2_match(struct device *, void *, void *); 237 void mvpp2_attach(struct device *, struct device *, void *); 238 void mvpp2_attach_deferred(struct device *); 239 240 const struct cfattach mvppc_ca = { 241 sizeof(struct mvpp2_softc), mvpp2_match, mvpp2_attach 242 }; 243 244 struct cfdriver mvppc_cd = { 245 NULL, "mvppc", DV_DULL 246 }; 247 248 int mvpp2_port_match(struct device *, void *, void *); 249 void mvpp2_port_attach(struct device *, struct device *, void *); 250 251 const struct cfattach mvpp_ca = { 252 sizeof(struct mvpp2_port), mvpp2_port_match, mvpp2_port_attach 253 }; 254 255 struct cfdriver mvpp_cd = { 256 NULL, "mvpp", DV_IFNET 257 }; 258 259 void mvpp2_port_attach_sfp(struct device *); 260 261 uint32_t mvpp2_read(struct mvpp2_softc *, bus_addr_t); 262 void mvpp2_write(struct mvpp2_softc *, bus_addr_t, uint32_t); 263 uint32_t mvpp2_gmac_read(struct mvpp2_port *, bus_addr_t); 264 void mvpp2_gmac_write(struct mvpp2_port *, bus_addr_t, uint32_t); 265 uint32_t mvpp2_xlg_read(struct mvpp2_port *, bus_addr_t); 266 void mvpp2_xlg_write(struct mvpp2_port *, bus_addr_t, uint32_t); 267 uint32_t mvpp2_xpcs_read(struct mvpp2_port *, bus_addr_t); 268 void mvpp2_xpcs_write(struct mvpp2_port *, bus_addr_t, uint32_t); 269 uint32_t mvpp2_mpcs_read(struct mvpp2_port *, bus_addr_t); 270 void mvpp2_mpcs_write(struct mvpp2_port *, bus_addr_t, uint32_t); 271 272 int mvpp2_ioctl(struct ifnet *, u_long, caddr_t); 273 void mvpp2_start(struct ifnet *); 274 int mvpp2_rxrinfo(struct mvpp2_port *, struct if_rxrinfo *); 275 void mvpp2_watchdog(struct ifnet *); 276 277 int mvpp2_media_change(struct ifnet *); 278 void mvpp2_media_status(struct ifnet *, struct ifmediareq *); 279 280 int mvpp2_mii_readreg(struct device *, int, int); 281 void mvpp2_mii_writereg(struct device *, int, int, int); 282 void mvpp2_mii_statchg(struct device *); 283 void mvpp2_inband_statchg(struct mvpp2_port *); 284 void mvpp2_port_change(struct mvpp2_port *); 285 286 void mvpp2_tick(void *); 287 288 int mvpp2_link_intr(void *); 289 int mvpp2_intr(void *); 290 void mvpp2_tx_proc(struct mvpp2_port *, uint8_t); 291 void mvpp2_txq_proc(struct mvpp2_port *, struct mvpp2_tx_queue *); 292 void mvpp2_rx_proc(struct mvpp2_port *, uint8_t); 293 void mvpp2_rxq_proc(struct mvpp2_port *, struct mvpp2_rx_queue *); 294 void mvpp2_rx_refill(struct mvpp2_port *); 295 296 void mvpp2_up(struct mvpp2_port *); 297 void mvpp2_down(struct mvpp2_port *); 298 void mvpp2_iff(struct mvpp2_port *); 299 300 void mvpp2_aggr_txq_hw_init(struct mvpp2_softc *, struct mvpp2_tx_queue *); 301 void mvpp2_txq_hw_init(struct mvpp2_port *, struct mvpp2_tx_queue *); 302 void mvpp2_rxq_hw_init(struct mvpp2_port *, struct mvpp2_rx_queue *); 303 void mvpp2_txq_hw_deinit(struct mvpp2_port *, struct mvpp2_tx_queue *); 304 void mvpp2_rxq_hw_drop(struct mvpp2_port *, struct mvpp2_rx_queue *); 305 void mvpp2_rxq_hw_deinit(struct mvpp2_port *, struct mvpp2_rx_queue *); 306 void mvpp2_rxq_long_pool_set(struct mvpp2_port *, int, int); 307 void mvpp2_rxq_short_pool_set(struct mvpp2_port *, int, int); 308 309 void mvpp2_mac_reset_assert(struct mvpp2_port *); 310 void mvpp2_pcs_reset_assert(struct mvpp2_port *); 311 void mvpp2_pcs_reset_deassert(struct mvpp2_port *); 312 void mvpp2_mac_config(struct mvpp2_port *); 313 void mvpp2_xlg_config(struct mvpp2_port *); 314 void mvpp2_gmac_config(struct mvpp2_port *); 315 void mvpp2_comphy_config(struct mvpp2_port *, int); 316 void mvpp2_gop_config(struct mvpp2_port *); 317 void mvpp2_gop_intr_mask(struct mvpp2_port *); 318 void mvpp2_gop_intr_unmask(struct mvpp2_port *); 319 320 struct mvpp2_dmamem * 321 mvpp2_dmamem_alloc(struct mvpp2_softc *, bus_size_t, bus_size_t); 322 void mvpp2_dmamem_free(struct mvpp2_softc *, struct mvpp2_dmamem *); 323 struct mbuf *mvpp2_alloc_mbuf(struct mvpp2_softc *, bus_dmamap_t); 324 325 void mvpp2_interrupts_enable(struct mvpp2_port *, int); 326 void mvpp2_interrupts_disable(struct mvpp2_port *, int); 327 int mvpp2_egress_port(struct mvpp2_port *); 328 int mvpp2_txq_phys(int, int); 329 void mvpp2_defaults_set(struct mvpp2_port *); 330 void mvpp2_ingress_enable(struct mvpp2_port *); 331 void mvpp2_ingress_disable(struct mvpp2_port *); 332 void mvpp2_egress_enable(struct mvpp2_port *); 333 void mvpp2_egress_disable(struct mvpp2_port *); 334 void mvpp2_port_enable(struct mvpp2_port *); 335 void mvpp2_port_disable(struct mvpp2_port *); 336 void mvpp2_rxq_status_update(struct mvpp2_port *, int, int, int); 337 int mvpp2_rxq_received(struct mvpp2_port *, int); 338 void mvpp2_rxq_offset_set(struct mvpp2_port *, int, int); 339 void mvpp2_txp_max_tx_size_set(struct mvpp2_port *); 340 void mvpp2_rx_pkts_coal_set(struct mvpp2_port *, struct mvpp2_rx_queue *, 341 uint32_t); 342 void mvpp2_tx_pkts_coal_set(struct mvpp2_port *, struct mvpp2_tx_queue *, 343 uint32_t); 344 void mvpp2_rx_time_coal_set(struct mvpp2_port *, struct mvpp2_rx_queue *, 345 uint32_t); 346 void mvpp2_tx_time_coal_set(struct mvpp2_port *, uint32_t); 347 348 void mvpp2_axi_config(struct mvpp2_softc *); 349 void mvpp2_bm_pool_init(struct mvpp2_softc *); 350 void mvpp2_rx_fifo_init(struct mvpp2_softc *); 351 void mvpp2_tx_fifo_init(struct mvpp2_softc *); 352 int mvpp2_prs_default_init(struct mvpp2_softc *); 353 void mvpp2_prs_hw_inv(struct mvpp2_softc *, int); 354 void mvpp2_prs_hw_port_init(struct mvpp2_softc *, int, int, int, int); 355 void mvpp2_prs_def_flow_init(struct mvpp2_softc *); 356 void mvpp2_prs_mh_init(struct mvpp2_softc *); 357 void mvpp2_prs_mac_init(struct mvpp2_softc *); 358 void mvpp2_prs_dsa_init(struct mvpp2_softc *); 359 int mvpp2_prs_etype_init(struct mvpp2_softc *); 360 int mvpp2_prs_vlan_init(struct mvpp2_softc *); 361 int mvpp2_prs_pppoe_init(struct mvpp2_softc *); 362 int mvpp2_prs_ip6_init(struct mvpp2_softc *); 363 int mvpp2_prs_ip4_init(struct mvpp2_softc *); 364 void mvpp2_prs_shadow_ri_set(struct mvpp2_softc *, int, 365 uint32_t, uint32_t); 366 void mvpp2_prs_tcam_lu_set(struct mvpp2_prs_entry *, uint32_t); 367 void mvpp2_prs_tcam_port_set(struct mvpp2_prs_entry *, uint32_t, int); 368 void mvpp2_prs_tcam_port_map_set(struct mvpp2_prs_entry *, uint32_t); 369 uint32_t mvpp2_prs_tcam_port_map_get(struct mvpp2_prs_entry *); 370 void mvpp2_prs_tcam_data_byte_set(struct mvpp2_prs_entry *, uint32_t, 371 uint8_t, uint8_t); 372 void mvpp2_prs_tcam_data_byte_get(struct mvpp2_prs_entry *, uint32_t, 373 uint8_t *, uint8_t *); 374 int mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *, int, uint16_t); 375 void mvpp2_prs_tcam_ai_update(struct mvpp2_prs_entry *, uint32_t, uint32_t); 376 int mvpp2_prs_sram_ai_get(struct mvpp2_prs_entry *); 377 int mvpp2_prs_tcam_ai_get(struct mvpp2_prs_entry *); 378 void mvpp2_prs_tcam_data_word_get(struct mvpp2_prs_entry *, uint32_t, 379 uint32_t *, uint32_t *); 380 void mvpp2_prs_match_etype(struct mvpp2_prs_entry *, uint32_t, uint16_t); 381 int mvpp2_prs_sram_ri_get(struct mvpp2_prs_entry *); 382 void mvpp2_prs_sram_ai_update(struct mvpp2_prs_entry *, uint32_t, uint32_t); 383 void mvpp2_prs_sram_ri_update(struct mvpp2_prs_entry *, uint32_t, uint32_t); 384 void mvpp2_prs_sram_bits_set(struct mvpp2_prs_entry *, uint32_t, uint32_t); 385 void mvpp2_prs_sram_bits_clear(struct mvpp2_prs_entry *, uint32_t, uint32_t); 386 void mvpp2_prs_sram_shift_set(struct mvpp2_prs_entry *, int, uint32_t); 387 void mvpp2_prs_sram_offset_set(struct mvpp2_prs_entry *, uint32_t, int, 388 uint32_t); 389 void mvpp2_prs_sram_next_lu_set(struct mvpp2_prs_entry *, uint32_t); 390 void mvpp2_prs_shadow_set(struct mvpp2_softc *, int, uint32_t); 391 int mvpp2_prs_hw_write(struct mvpp2_softc *, struct mvpp2_prs_entry *); 392 int mvpp2_prs_hw_read(struct mvpp2_softc *, struct mvpp2_prs_entry *, int); 393 int mvpp2_prs_flow_find(struct mvpp2_softc *, int); 394 int mvpp2_prs_tcam_first_free(struct mvpp2_softc *, uint8_t, uint8_t); 395 void mvpp2_prs_mac_drop_all_set(struct mvpp2_softc *, uint32_t, int); 396 void mvpp2_prs_mac_promisc_set(struct mvpp2_softc *, uint32_t, int, int); 397 void mvpp2_prs_dsa_tag_set(struct mvpp2_softc *, uint32_t, int, int, int); 398 void mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2_softc *, uint32_t, 399 int, int, int); 400 struct mvpp2_prs_entry *mvpp2_prs_vlan_find(struct mvpp2_softc *, uint16_t, 401 int); 402 int mvpp2_prs_vlan_add(struct mvpp2_softc *, uint16_t, int, uint32_t); 403 int mvpp2_prs_double_vlan_ai_free_get(struct mvpp2_softc *); 404 struct mvpp2_prs_entry *mvpp2_prs_double_vlan_find(struct mvpp2_softc *, 405 uint16_t, uint16_t); 406 int mvpp2_prs_double_vlan_add(struct mvpp2_softc *, uint16_t, uint16_t, 407 uint32_t); 408 int mvpp2_prs_ip4_proto(struct mvpp2_softc *, uint16_t, uint32_t, uint32_t); 409 int mvpp2_prs_ip4_cast(struct mvpp2_softc *, uint16_t); 410 int mvpp2_prs_ip6_proto(struct mvpp2_softc *, uint16_t, uint32_t, uint32_t); 411 int mvpp2_prs_ip6_cast(struct mvpp2_softc *, uint16_t); 412 int mvpp2_prs_mac_da_range_find(struct mvpp2_softc *, int, const uint8_t *, 413 uint8_t *, int); 414 int mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *, const uint8_t *, 415 uint8_t *); 416 int mvpp2_prs_mac_da_accept(struct mvpp2_port *, const uint8_t *, int); 417 void mvpp2_prs_mac_del_all(struct mvpp2_port *); 418 int mvpp2_prs_tag_mode_set(struct mvpp2_softc *, int, int); 419 int mvpp2_prs_def_flow(struct mvpp2_port *); 420 void mvpp2_cls_flow_write(struct mvpp2_softc *, struct mvpp2_cls_flow_entry *); 421 void mvpp2_cls_lookup_write(struct mvpp2_softc *, struct mvpp2_cls_lookup_entry *); 422 void mvpp2_cls_init(struct mvpp2_softc *); 423 void mvpp2_cls_port_config(struct mvpp2_port *); 424 void mvpp2_cls_oversize_rxq_set(struct mvpp2_port *); 425 426 int 427 mvpp2_match(struct device *parent, void *cfdata, void *aux) 428 { 429 struct fdt_attach_args *faa = aux; 430 431 return OF_is_compatible(faa->fa_node, "marvell,armada-7k-pp22"); 432 } 433 434 void 435 mvpp2_attach(struct device *parent, struct device *self, void *aux) 436 { 437 struct mvpp2_softc *sc = (void *)self; 438 struct fdt_attach_args *faa = aux; 439 440 if (faa->fa_nreg < 2) { 441 printf(": no registers\n"); 442 return; 443 } 444 445 sc->sc_node = faa->fa_node; 446 sc->sc_iot = faa->fa_iot; 447 sc->sc_dmat = faa->fa_dmat; 448 449 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 450 faa->fa_reg[0].size, 0, &sc->sc_ioh_base)) { 451 printf(": can't map registers\n"); 452 return; 453 } 454 sc->sc_iosize_base = faa->fa_reg[0].size; 455 456 sc->sc_ioh_paddr = bus_space_mmap(sc->sc_iot, faa->fa_reg[0].addr, 457 0, PROT_READ | PROT_WRITE, 0); 458 KASSERT(sc->sc_ioh_paddr != -1); 459 sc->sc_ioh_paddr &= PMAP_PA_MASK; 460 461 if (bus_space_map(sc->sc_iot, faa->fa_reg[1].addr, 462 faa->fa_reg[1].size, 0, &sc->sc_ioh_iface)) { 463 printf(": can't map registers\n"); 464 bus_space_unmap(sc->sc_iot, sc->sc_ioh_base, 465 sc->sc_iosize_base); 466 return; 467 } 468 sc->sc_iosize_iface = faa->fa_reg[1].size; 469 470 sc->sc_rm = regmap_byphandle(OF_getpropint(faa->fa_node, 471 "marvell,system-controller", 0)); 472 473 clock_enable_all(faa->fa_node); 474 sc->sc_tclk = clock_get_frequency(faa->fa_node, "pp_clk"); 475 476 printf("\n"); 477 478 config_defer(self, mvpp2_attach_deferred); 479 } 480 481 void 482 mvpp2_attach_deferred(struct device *self) 483 { 484 struct mvpp2_softc *sc = (void *)self; 485 struct mvpp2_attach_args maa; 486 struct mvpp2_tx_queue *txq; 487 int i, node; 488 489 mvpp2_axi_config(sc); 490 491 bus_space_write_4(sc->sc_iot, sc->sc_ioh_iface, MVPP22_SMI_MISC_CFG_REG, 492 bus_space_read_4(sc->sc_iot, sc->sc_ioh_iface, 493 MVPP22_SMI_MISC_CFG_REG) & ~MVPP22_SMI_POLLING_EN); 494 495 sc->sc_aggr_ntxq = 1; 496 sc->sc_aggr_txqs = mallocarray(sc->sc_aggr_ntxq, 497 sizeof(*sc->sc_aggr_txqs), M_DEVBUF, M_WAITOK | M_ZERO); 498 499 for (i = 0; i < sc->sc_aggr_ntxq; i++) { 500 txq = &sc->sc_aggr_txqs[i]; 501 txq->id = i; 502 mvpp2_aggr_txq_hw_init(sc, txq); 503 } 504 505 mvpp2_rx_fifo_init(sc); 506 mvpp2_tx_fifo_init(sc); 507 508 mvpp2_write(sc, MVPP2_TX_SNOOP_REG, 0x1); 509 510 mvpp2_bm_pool_init(sc); 511 512 sc->sc_prs_shadow = mallocarray(MVPP2_PRS_TCAM_SRAM_SIZE, 513 sizeof(*sc->sc_prs_shadow), M_DEVBUF, M_WAITOK | M_ZERO); 514 515 mvpp2_prs_default_init(sc); 516 mvpp2_cls_init(sc); 517 518 memset(&maa, 0, sizeof(maa)); 519 for (node = OF_child(sc->sc_node); node; node = OF_peer(node)) { 520 maa.ma_node = node; 521 maa.ma_dmat = sc->sc_dmat; 522 config_found(self, &maa, NULL); 523 } 524 } 525 526 void 527 mvpp2_axi_config(struct mvpp2_softc *sc) 528 { 529 uint32_t reg; 530 531 mvpp2_write(sc, MVPP22_BM_ADDR_HIGH_RLS_REG, 0); 532 533 reg = (MVPP22_AXI_CODE_CACHE_WR_CACHE << MVPP22_AXI_ATTR_CACHE_OFFS) | 534 (MVPP22_AXI_CODE_DOMAIN_OUTER_DOM << MVPP22_AXI_ATTR_DOMAIN_OFFS); 535 mvpp2_write(sc, MVPP22_AXI_BM_WR_ATTR_REG, reg); 536 mvpp2_write(sc, MVPP22_AXI_TXQ_DESCR_WR_ATTR_REG, reg); 537 mvpp2_write(sc, MVPP22_AXI_RXQ_DESCR_WR_ATTR_REG, reg); 538 mvpp2_write(sc, MVPP22_AXI_RX_DATA_WR_ATTR_REG, reg); 539 540 reg = (MVPP22_AXI_CODE_CACHE_RD_CACHE << MVPP22_AXI_ATTR_CACHE_OFFS) | 541 (MVPP22_AXI_CODE_DOMAIN_OUTER_DOM << MVPP22_AXI_ATTR_DOMAIN_OFFS); 542 mvpp2_write(sc, MVPP22_AXI_BM_RD_ATTR_REG, reg); 543 mvpp2_write(sc, MVPP22_AXI_AGGRQ_DESCR_RD_ATTR_REG, reg); 544 mvpp2_write(sc, MVPP22_AXI_TXQ_DESCR_RD_ATTR_REG, reg); 545 mvpp2_write(sc, MVPP22_AXI_TX_DATA_RD_ATTR_REG, reg); 546 547 reg = (MVPP22_AXI_CODE_CACHE_NON_CACHE << MVPP22_AXI_CODE_CACHE_OFFS) | 548 (MVPP22_AXI_CODE_DOMAIN_SYSTEM << MVPP22_AXI_CODE_DOMAIN_OFFS); 549 mvpp2_write(sc, MVPP22_AXI_RD_NORMAL_CODE_REG, reg); 550 mvpp2_write(sc, MVPP22_AXI_WR_NORMAL_CODE_REG, reg); 551 552 reg = (MVPP22_AXI_CODE_CACHE_RD_CACHE << MVPP22_AXI_CODE_CACHE_OFFS) | 553 (MVPP22_AXI_CODE_DOMAIN_OUTER_DOM << MVPP22_AXI_CODE_DOMAIN_OFFS); 554 mvpp2_write(sc, MVPP22_AXI_RD_SNOOP_CODE_REG, reg); 555 556 reg = (MVPP22_AXI_CODE_CACHE_WR_CACHE << MVPP22_AXI_CODE_CACHE_OFFS) | 557 (MVPP22_AXI_CODE_DOMAIN_OUTER_DOM << MVPP22_AXI_CODE_DOMAIN_OFFS); 558 mvpp2_write(sc, MVPP22_AXI_WR_SNOOP_CODE_REG, reg); 559 } 560 561 void 562 mvpp2_bm_pool_init(struct mvpp2_softc *sc) 563 { 564 struct mvpp2_bm_pool *bm; 565 struct mvpp2_buf *rxb; 566 uint64_t phys, virt; 567 int i, j, inuse; 568 569 for (i = 0; i < MVPP2_BM_POOLS_NUM; i++) { 570 mvpp2_write(sc, MVPP2_BM_INTR_MASK_REG(i), 0); 571 mvpp2_write(sc, MVPP2_BM_INTR_CAUSE_REG(i), 0); 572 } 573 574 sc->sc_npools = ncpus; 575 sc->sc_npools = min(sc->sc_npools, MVPP2_BM_POOLS_NUM); 576 577 sc->sc_bm_pools = mallocarray(sc->sc_npools, sizeof(*sc->sc_bm_pools), 578 M_DEVBUF, M_WAITOK | M_ZERO); 579 580 for (i = 0; i < sc->sc_npools; i++) { 581 bm = &sc->sc_bm_pools[i]; 582 bm->bm_mem = mvpp2_dmamem_alloc(sc, 583 MVPP2_BM_SIZE * sizeof(uint64_t) * 2, 584 MVPP2_BM_POOL_PTR_ALIGN); 585 KASSERT(bm->bm_mem != NULL); 586 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(bm->bm_mem), 0, 587 MVPP2_DMA_LEN(bm->bm_mem), 588 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 589 590 mvpp2_write(sc, MVPP2_BM_POOL_CTRL_REG(i), 591 mvpp2_read(sc, MVPP2_BM_POOL_CTRL_REG(i)) | 592 MVPP2_BM_STOP_MASK); 593 594 mvpp2_write(sc, MVPP2_BM_POOL_BASE_REG(i), 595 (uint64_t)MVPP2_DMA_DVA(bm->bm_mem) & 0xffffffff); 596 mvpp2_write(sc, MVPP22_BM_POOL_BASE_HIGH_REG, 597 ((uint64_t)MVPP2_DMA_DVA(bm->bm_mem) >> 32) 598 & MVPP22_BM_POOL_BASE_HIGH_MASK); 599 mvpp2_write(sc, MVPP2_BM_POOL_SIZE_REG(i), 600 MVPP2_BM_SIZE); 601 602 mvpp2_write(sc, MVPP2_BM_POOL_CTRL_REG(i), 603 mvpp2_read(sc, MVPP2_BM_POOL_CTRL_REG(i)) | 604 MVPP2_BM_START_MASK); 605 606 /* 607 * U-Boot might not have cleaned its pools. The pool needs 608 * to be empty before we fill it, otherwise our packets are 609 * written to wherever U-Boot allocated memory. Cleaning it 610 * up ourselves is worrying as well, since the BM's pages are 611 * probably in our own memory. Best we can do is stop the BM, 612 * set new memory and drain the pool. 613 */ 614 inuse = mvpp2_read(sc, MVPP2_BM_POOL_PTRS_NUM_REG(i)) & 615 MVPP2_BM_POOL_PTRS_NUM_MASK; 616 inuse += mvpp2_read(sc, MVPP2_BM_BPPI_PTRS_NUM_REG(i)) & 617 MVPP2_BM_BPPI_PTRS_NUM_MASK; 618 if (inuse) 619 inuse++; 620 for (j = 0; j < inuse; j++) 621 mvpp2_read(sc, MVPP2_BM_PHY_ALLOC_REG(i)); 622 623 mvpp2_write(sc, MVPP2_POOL_BUF_SIZE_REG(i), 624 roundup(MCLBYTES, 1 << MVPP2_POOL_BUF_SIZE_OFFSET)); 625 626 bm->rxbuf = mallocarray(MVPP2_BM_SIZE, sizeof(struct mvpp2_buf), 627 M_DEVBUF, M_WAITOK); 628 bm->freelist = mallocarray(MVPP2_BM_SIZE, sizeof(*bm->freelist), 629 M_DEVBUF, M_WAITOK | M_ZERO); 630 631 for (j = 0; j < MVPP2_BM_SIZE; j++) { 632 rxb = &bm->rxbuf[j]; 633 bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 634 MCLBYTES, 0, BUS_DMA_WAITOK, &rxb->mb_map); 635 rxb->mb_m = NULL; 636 } 637 638 /* Use pool-id and rxbuf index as cookie. */ 639 for (j = 0; j < MVPP2_BM_SIZE; j++) 640 bm->freelist[j] = (i << 16) | (j << 0); 641 642 for (j = 0; j < MVPP2_BM_SIZE; j++) { 643 rxb = &bm->rxbuf[j]; 644 rxb->mb_m = mvpp2_alloc_mbuf(sc, rxb->mb_map); 645 if (rxb->mb_m == NULL) 646 break; 647 648 KASSERT(bm->freelist[bm->free_cons] != -1); 649 virt = bm->freelist[bm->free_cons]; 650 bm->freelist[bm->free_cons] = -1; 651 bm->free_cons = (bm->free_cons + 1) % MVPP2_BM_SIZE; 652 653 phys = rxb->mb_map->dm_segs[0].ds_addr; 654 mvpp2_write(sc, MVPP22_BM_ADDR_HIGH_RLS_REG, 655 (((virt >> 32) & MVPP22_ADDR_HIGH_MASK) 656 << MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT) | 657 ((phys >> 32) & MVPP22_ADDR_HIGH_MASK)); 658 mvpp2_write(sc, MVPP2_BM_VIRT_RLS_REG, 659 virt & 0xffffffff); 660 mvpp2_write(sc, MVPP2_BM_PHY_RLS_REG(i), 661 phys & 0xffffffff); 662 } 663 } 664 } 665 666 void 667 mvpp2_rx_fifo_init(struct mvpp2_softc *sc) 668 { 669 int i; 670 671 mvpp2_write(sc, MVPP2_RX_DATA_FIFO_SIZE_REG(0), 672 MVPP2_RX_FIFO_PORT_DATA_SIZE_32KB); 673 mvpp2_write(sc, MVPP2_RX_ATTR_FIFO_SIZE_REG(0), 674 MVPP2_RX_FIFO_PORT_ATTR_SIZE_32KB); 675 676 mvpp2_write(sc, MVPP2_RX_DATA_FIFO_SIZE_REG(1), 677 MVPP2_RX_FIFO_PORT_DATA_SIZE_8KB); 678 mvpp2_write(sc, MVPP2_RX_ATTR_FIFO_SIZE_REG(1), 679 MVPP2_RX_FIFO_PORT_ATTR_SIZE_8KB); 680 681 for (i = 2; i < MVPP2_MAX_PORTS; i++) { 682 mvpp2_write(sc, MVPP2_RX_DATA_FIFO_SIZE_REG(i), 683 MVPP2_RX_FIFO_PORT_DATA_SIZE_4KB); 684 mvpp2_write(sc, MVPP2_RX_ATTR_FIFO_SIZE_REG(i), 685 MVPP2_RX_FIFO_PORT_ATTR_SIZE_4KB); 686 } 687 688 mvpp2_write(sc, MVPP2_RX_MIN_PKT_SIZE_REG, MVPP2_RX_FIFO_PORT_MIN_PKT); 689 mvpp2_write(sc, MVPP2_RX_FIFO_INIT_REG, 0x1); 690 } 691 692 void 693 mvpp2_tx_fifo_init(struct mvpp2_softc *sc) 694 { 695 int i; 696 697 mvpp2_write(sc, MVPP22_TX_FIFO_SIZE_REG(0), 698 MVPP22_TX_FIFO_DATA_SIZE_10KB); 699 mvpp2_write(sc, MVPP22_TX_FIFO_THRESH_REG(0), 700 MVPP2_TX_FIFO_THRESHOLD_10KB); 701 702 for (i = 1; i < MVPP2_MAX_PORTS; i++) { 703 mvpp2_write(sc, MVPP22_TX_FIFO_SIZE_REG(i), 704 MVPP22_TX_FIFO_DATA_SIZE_3KB); 705 mvpp2_write(sc, MVPP22_TX_FIFO_THRESH_REG(i), 706 MVPP2_TX_FIFO_THRESHOLD_3KB); 707 } 708 } 709 710 int 711 mvpp2_prs_default_init(struct mvpp2_softc *sc) 712 { 713 int i, j, ret; 714 715 mvpp2_write(sc, MVPP2_PRS_TCAM_CTRL_REG, MVPP2_PRS_TCAM_EN_MASK); 716 717 for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) { 718 mvpp2_write(sc, MVPP2_PRS_TCAM_IDX_REG, i); 719 for (j = 0; j < MVPP2_PRS_TCAM_WORDS; j++) 720 mvpp2_write(sc, MVPP2_PRS_TCAM_DATA_REG(j), 0); 721 722 mvpp2_write(sc, MVPP2_PRS_SRAM_IDX_REG, i); 723 for (j = 0; j < MVPP2_PRS_SRAM_WORDS; j++) 724 mvpp2_write(sc, MVPP2_PRS_SRAM_DATA_REG(j), 0); 725 } 726 727 for (i = 0; i < MVPP2_PRS_TCAM_SRAM_SIZE; i++) 728 mvpp2_prs_hw_inv(sc, i); 729 730 for (i = 0; i < MVPP2_MAX_PORTS; i++) 731 mvpp2_prs_hw_port_init(sc, i, MVPP2_PRS_LU_MH, 732 MVPP2_PRS_PORT_LU_MAX, 0); 733 734 mvpp2_prs_def_flow_init(sc); 735 mvpp2_prs_mh_init(sc); 736 mvpp2_prs_mac_init(sc); 737 mvpp2_prs_dsa_init(sc); 738 ret = mvpp2_prs_etype_init(sc); 739 if (ret) 740 return ret; 741 ret = mvpp2_prs_vlan_init(sc); 742 if (ret) 743 return ret; 744 ret = mvpp2_prs_pppoe_init(sc); 745 if (ret) 746 return ret; 747 ret = mvpp2_prs_ip6_init(sc); 748 if (ret) 749 return ret; 750 ret = mvpp2_prs_ip4_init(sc); 751 if (ret) 752 return ret; 753 754 return 0; 755 } 756 757 void 758 mvpp2_prs_hw_inv(struct mvpp2_softc *sc, int index) 759 { 760 mvpp2_write(sc, MVPP2_PRS_TCAM_IDX_REG, index); 761 mvpp2_write(sc, MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD), 762 MVPP2_PRS_TCAM_INV_MASK); 763 } 764 765 void 766 mvpp2_prs_hw_port_init(struct mvpp2_softc *sc, int port, 767 int lu_first, int lu_max, int offset) 768 { 769 uint32_t reg; 770 771 reg = mvpp2_read(sc, MVPP2_PRS_INIT_LOOKUP_REG); 772 reg &= ~MVPP2_PRS_PORT_LU_MASK(port); 773 reg |= MVPP2_PRS_PORT_LU_VAL(port, lu_first); 774 mvpp2_write(sc, MVPP2_PRS_INIT_LOOKUP_REG, reg); 775 776 reg = mvpp2_read(sc, MVPP2_PRS_MAX_LOOP_REG(port)); 777 reg &= ~MVPP2_PRS_MAX_LOOP_MASK(port); 778 reg |= MVPP2_PRS_MAX_LOOP_VAL(port, lu_max); 779 mvpp2_write(sc, MVPP2_PRS_MAX_LOOP_REG(port), reg); 780 781 reg = mvpp2_read(sc, MVPP2_PRS_INIT_OFFS_REG(port)); 782 reg &= ~MVPP2_PRS_INIT_OFF_MASK(port); 783 reg |= MVPP2_PRS_INIT_OFF_VAL(port, offset); 784 mvpp2_write(sc, MVPP2_PRS_INIT_OFFS_REG(port), reg); 785 } 786 787 void 788 mvpp2_prs_def_flow_init(struct mvpp2_softc *sc) 789 { 790 struct mvpp2_prs_entry pe; 791 int i; 792 793 for (i = 0; i < MVPP2_MAX_PORTS; i++) { 794 memset(&pe, 0, sizeof(pe)); 795 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 796 pe.index = MVPP2_PE_FIRST_DEFAULT_FLOW - i; 797 mvpp2_prs_tcam_port_map_set(&pe, 0); 798 mvpp2_prs_sram_ai_update(&pe, i, MVPP2_PRS_FLOW_ID_MASK); 799 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1); 800 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_FLOWS); 801 mvpp2_prs_hw_write(sc, &pe); 802 } 803 } 804 805 void 806 mvpp2_prs_mh_init(struct mvpp2_softc *sc) 807 { 808 struct mvpp2_prs_entry pe; 809 810 memset(&pe, 0, sizeof(pe)); 811 pe.index = MVPP2_PE_MH_DEFAULT; 812 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MH); 813 mvpp2_prs_sram_shift_set(&pe, MVPP2_MH_SIZE, 814 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 815 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_MAC); 816 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 817 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MH); 818 mvpp2_prs_hw_write(sc, &pe); 819 } 820 821 void 822 mvpp2_prs_mac_init(struct mvpp2_softc *sc) 823 { 824 struct mvpp2_prs_entry pe; 825 826 memset(&pe, 0, sizeof(pe)); 827 pe.index = MVPP2_PE_MAC_NON_PROMISCUOUS; 828 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); 829 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK, 830 MVPP2_PRS_RI_DROP_MASK); 831 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 832 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 833 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 834 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC); 835 mvpp2_prs_hw_write(sc, &pe); 836 mvpp2_prs_mac_drop_all_set(sc, 0, 0); 837 mvpp2_prs_mac_promisc_set(sc, 0, MVPP2_PRS_L2_UNI_CAST, 0); 838 mvpp2_prs_mac_promisc_set(sc, 0, MVPP2_PRS_L2_MULTI_CAST, 0); 839 } 840 841 void 842 mvpp2_prs_dsa_init(struct mvpp2_softc *sc) 843 { 844 struct mvpp2_prs_entry pe; 845 846 mvpp2_prs_dsa_tag_set(sc, 0, 0, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA); 847 mvpp2_prs_dsa_tag_set(sc, 0, 0, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA); 848 mvpp2_prs_dsa_tag_set(sc, 0, 0, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA); 849 mvpp2_prs_dsa_tag_set(sc, 0, 0, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA); 850 mvpp2_prs_dsa_tag_ethertype_set(sc, 0, 0, MVPP2_PRS_UNTAGGED, MVPP2_PRS_EDSA); 851 mvpp2_prs_dsa_tag_ethertype_set(sc, 0, 0, MVPP2_PRS_TAGGED, MVPP2_PRS_EDSA); 852 mvpp2_prs_dsa_tag_ethertype_set(sc, 0, 1, MVPP2_PRS_UNTAGGED, MVPP2_PRS_DSA); 853 mvpp2_prs_dsa_tag_ethertype_set(sc, 0, 1, MVPP2_PRS_TAGGED, MVPP2_PRS_DSA); 854 memset(&pe, 0, sizeof(pe)); 855 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA); 856 pe.index = MVPP2_PE_DSA_DEFAULT; 857 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN); 858 mvpp2_prs_sram_shift_set(&pe, 0, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 859 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC); 860 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK); 861 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 862 mvpp2_prs_hw_write(sc, &pe); 863 } 864 865 int 866 mvpp2_prs_etype_init(struct mvpp2_softc *sc) 867 { 868 struct mvpp2_prs_entry pe; 869 int tid; 870 871 /* Ethertype: PPPoE */ 872 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 873 MVPP2_PE_LAST_FREE_TID); 874 if (tid < 0) 875 return tid; 876 memset(&pe, 0, sizeof(pe)); 877 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2); 878 pe.index = tid; 879 mvpp2_prs_match_etype(&pe, 0, ETHERTYPE_PPPOE); 880 mvpp2_prs_sram_shift_set(&pe, MVPP2_PPPOE_HDR_SIZE, 881 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 882 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_PPPOE); 883 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_PPPOE_MASK, 884 MVPP2_PRS_RI_PPPOE_MASK); 885 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2); 886 sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF; 887 sc->sc_prs_shadow[pe.index].finish = 0; 888 mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_PPPOE_MASK, 889 MVPP2_PRS_RI_PPPOE_MASK); 890 mvpp2_prs_hw_write(sc, &pe); 891 892 /* Ethertype: ARP */ 893 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 894 MVPP2_PE_LAST_FREE_TID); 895 if (tid < 0) 896 return tid; 897 memset(&pe, 0, sizeof(pe)); 898 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2); 899 pe.index = tid; 900 mvpp2_prs_match_etype(&pe, 0, ETHERTYPE_ARP); 901 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 902 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 903 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_ARP, 904 MVPP2_PRS_RI_L3_PROTO_MASK); 905 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, 906 MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 907 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2); 908 sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF; 909 sc->sc_prs_shadow[pe.index].finish = 1; 910 mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_ARP, 911 MVPP2_PRS_RI_L3_PROTO_MASK); 912 mvpp2_prs_hw_write(sc, &pe); 913 914 /* Ethertype: LBTD */ 915 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 916 MVPP2_PE_LAST_FREE_TID); 917 if (tid < 0) 918 return tid; 919 memset(&pe, 0, sizeof(pe)); 920 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2); 921 pe.index = tid; 922 mvpp2_prs_match_etype(&pe, 0, MVPP2_IP_LBDT_TYPE); 923 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 924 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 925 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_CPU_CODE_RX_SPEC | 926 MVPP2_PRS_RI_UDF3_RX_SPECIAL, MVPP2_PRS_RI_CPU_CODE_MASK | 927 MVPP2_PRS_RI_UDF3_MASK); 928 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, 929 MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 930 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2); 931 sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF; 932 sc->sc_prs_shadow[pe.index].finish = 1; 933 mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_CPU_CODE_RX_SPEC | 934 MVPP2_PRS_RI_UDF3_RX_SPECIAL, MVPP2_PRS_RI_CPU_CODE_MASK | 935 MVPP2_PRS_RI_UDF3_MASK); 936 mvpp2_prs_hw_write(sc, &pe); 937 938 /* Ethertype: IPv4 without options */ 939 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 940 MVPP2_PE_LAST_FREE_TID); 941 if (tid < 0) 942 return tid; 943 memset(&pe, 0, sizeof(pe)); 944 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2); 945 pe.index = tid; 946 mvpp2_prs_match_etype(&pe, 0, ETHERTYPE_IP); 947 mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN, 948 MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL, 949 MVPP2_PRS_IPV4_HEAD_MASK | MVPP2_PRS_IPV4_IHL_MASK); 950 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4); 951 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4, 952 MVPP2_PRS_RI_L3_PROTO_MASK); 953 mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4, 954 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 955 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, 956 MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 957 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2); 958 sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF; 959 sc->sc_prs_shadow[pe.index].finish = 0; 960 mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_IP4, 961 MVPP2_PRS_RI_L3_PROTO_MASK); 962 mvpp2_prs_hw_write(sc, &pe); 963 964 /* Ethertype: IPv4 with options */ 965 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 966 MVPP2_PE_LAST_FREE_TID); 967 if (tid < 0) 968 return tid; 969 pe.index = tid; 970 971 pe.tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(MVPP2_ETH_TYPE_LEN)] = 0x0; 972 pe.tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(MVPP2_ETH_TYPE_LEN)] = 0x0; 973 mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN, 974 MVPP2_PRS_IPV4_HEAD, MVPP2_PRS_IPV4_HEAD_MASK); 975 pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0; 976 pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0; 977 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT, 978 MVPP2_PRS_RI_L3_PROTO_MASK); 979 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2); 980 sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF; 981 sc->sc_prs_shadow[pe.index].finish = 0; 982 mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_IP4_OPT, 983 MVPP2_PRS_RI_L3_PROTO_MASK); 984 mvpp2_prs_hw_write(sc, &pe); 985 986 /* Ethertype: IPv6 without options */ 987 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 988 MVPP2_PE_LAST_FREE_TID); 989 if (tid < 0) 990 return tid; 991 memset(&pe, 0, sizeof(pe)); 992 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2); 993 pe.index = tid; 994 mvpp2_prs_match_etype(&pe, 0, ETHERTYPE_IPV6); 995 mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 8 + 996 MVPP2_MAX_L3_ADDR_SIZE, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 997 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); 998 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6, 999 MVPP2_PRS_RI_L3_PROTO_MASK); 1000 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, 1001 MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 1002 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2); 1003 sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF; 1004 sc->sc_prs_shadow[pe.index].finish = 0; 1005 mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_IP6, 1006 MVPP2_PRS_RI_L3_PROTO_MASK); 1007 mvpp2_prs_hw_write(sc, &pe); 1008 1009 /* Default entry for MVPP2_PRS_LU_L2 - Unknown ethtype */ 1010 memset(&pe, 0, sizeof(pe)); 1011 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_L2); 1012 pe.index = MVPP2_PE_ETH_TYPE_UN; 1013 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 1014 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 1015 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 1016 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN, 1017 MVPP2_PRS_RI_L3_PROTO_MASK); 1018 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, 1019 MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 1020 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_L2); 1021 sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_L2_DEF; 1022 sc->sc_prs_shadow[pe.index].finish = 1; 1023 mvpp2_prs_shadow_ri_set(sc, pe.index, MVPP2_PRS_RI_L3_UN, 1024 MVPP2_PRS_RI_L3_PROTO_MASK); 1025 mvpp2_prs_hw_write(sc, &pe); 1026 1027 return 0; 1028 } 1029 1030 int 1031 mvpp2_prs_vlan_init(struct mvpp2_softc *sc) 1032 { 1033 struct mvpp2_prs_entry pe; 1034 int ret; 1035 1036 sc->sc_prs_double_vlans = mallocarray(MVPP2_PRS_DBL_VLANS_MAX, 1037 sizeof(*sc->sc_prs_double_vlans), M_DEVBUF, M_WAITOK | M_ZERO); 1038 1039 ret = mvpp2_prs_double_vlan_add(sc, ETHERTYPE_VLAN, ETHERTYPE_QINQ, 1040 MVPP2_PRS_PORT_MASK); 1041 if (ret) 1042 return ret; 1043 ret = mvpp2_prs_double_vlan_add(sc, ETHERTYPE_VLAN, ETHERTYPE_VLAN, 1044 MVPP2_PRS_PORT_MASK); 1045 if (ret) 1046 return ret; 1047 ret = mvpp2_prs_vlan_add(sc, ETHERTYPE_QINQ, MVPP2_PRS_SINGLE_VLAN_AI, 1048 MVPP2_PRS_PORT_MASK); 1049 if (ret) 1050 return ret; 1051 ret = mvpp2_prs_vlan_add(sc, ETHERTYPE_VLAN, MVPP2_PRS_SINGLE_VLAN_AI, 1052 MVPP2_PRS_PORT_MASK); 1053 if (ret) 1054 return ret; 1055 1056 memset(&pe, 0, sizeof(pe)); 1057 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN); 1058 pe.index = MVPP2_PE_VLAN_DBL; 1059 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2); 1060 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK); 1061 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_DOUBLE, 1062 MVPP2_PRS_RI_VLAN_MASK); 1063 mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_DBL_VLAN_AI_BIT, 1064 MVPP2_PRS_DBL_VLAN_AI_BIT); 1065 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 1066 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_VLAN); 1067 mvpp2_prs_hw_write(sc, &pe); 1068 1069 memset(&pe, 0, sizeof(pe)); 1070 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_VLAN); 1071 pe.index = MVPP2_PE_VLAN_NONE; 1072 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2); 1073 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE, 1074 MVPP2_PRS_RI_VLAN_MASK); 1075 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 1076 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_VLAN); 1077 mvpp2_prs_hw_write(sc, &pe); 1078 1079 return 0; 1080 } 1081 1082 int 1083 mvpp2_prs_pppoe_init(struct mvpp2_softc *sc) 1084 { 1085 struct mvpp2_prs_entry pe; 1086 int tid; 1087 1088 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 1089 MVPP2_PE_LAST_FREE_TID); 1090 if (tid < 0) 1091 return tid; 1092 1093 memset(&pe, 0, sizeof(pe)); 1094 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE); 1095 pe.index = tid; 1096 mvpp2_prs_match_etype(&pe, 0, PPP_IP); 1097 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4); 1098 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4_OPT, 1099 MVPP2_PRS_RI_L3_PROTO_MASK); 1100 mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4, 1101 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 1102 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, 1103 MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 1104 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_PPPOE); 1105 mvpp2_prs_hw_write(sc, &pe); 1106 1107 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 1108 MVPP2_PE_LAST_FREE_TID); 1109 if (tid < 0) 1110 return tid; 1111 1112 pe.index = tid; 1113 mvpp2_prs_tcam_data_byte_set(&pe, MVPP2_ETH_TYPE_LEN, 1114 MVPP2_PRS_IPV4_HEAD | MVPP2_PRS_IPV4_IHL, 1115 MVPP2_PRS_IPV4_HEAD_MASK | MVPP2_PRS_IPV4_IHL_MASK); 1116 pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0; 1117 pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0; 1118 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP4, MVPP2_PRS_RI_L3_PROTO_MASK); 1119 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_PPPOE); 1120 mvpp2_prs_hw_write(sc, &pe); 1121 1122 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 1123 MVPP2_PE_LAST_FREE_TID); 1124 if (tid < 0) 1125 return tid; 1126 1127 memset(&pe, 0, sizeof(pe)); 1128 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE); 1129 pe.index = tid; 1130 mvpp2_prs_match_etype(&pe, 0, PPP_IPV6); 1131 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); 1132 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_IP6, 1133 MVPP2_PRS_RI_L3_PROTO_MASK); 1134 mvpp2_prs_sram_shift_set(&pe, MVPP2_ETH_TYPE_LEN + 4, 1135 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 1136 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, 1137 MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 1138 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_PPPOE); 1139 mvpp2_prs_hw_write(sc, &pe); 1140 1141 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 1142 MVPP2_PE_LAST_FREE_TID); 1143 if (tid < 0) 1144 return tid; 1145 1146 memset(&pe, 0, sizeof(pe)); 1147 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_PPPOE); 1148 pe.index = tid; 1149 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UN, 1150 MVPP2_PRS_RI_L3_PROTO_MASK); 1151 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 1152 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 1153 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L3, 1154 MVPP2_ETH_TYPE_LEN, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 1155 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_PPPOE); 1156 mvpp2_prs_hw_write(sc, &pe); 1157 1158 return 0; 1159 } 1160 1161 int 1162 mvpp2_prs_ip6_init(struct mvpp2_softc *sc) 1163 { 1164 struct mvpp2_prs_entry pe; 1165 int tid, ret; 1166 1167 ret = mvpp2_prs_ip6_proto(sc, IPPROTO_TCP, MVPP2_PRS_RI_L4_TCP, 1168 MVPP2_PRS_RI_L4_PROTO_MASK); 1169 if (ret) 1170 return ret; 1171 ret = mvpp2_prs_ip6_proto(sc, IPPROTO_UDP, MVPP2_PRS_RI_L4_UDP, 1172 MVPP2_PRS_RI_L4_PROTO_MASK); 1173 if (ret) 1174 return ret; 1175 ret = mvpp2_prs_ip6_proto(sc, IPPROTO_ICMPV6, 1176 MVPP2_PRS_RI_CPU_CODE_RX_SPEC | MVPP2_PRS_RI_UDF3_RX_SPECIAL, 1177 MVPP2_PRS_RI_CPU_CODE_MASK | MVPP2_PRS_RI_UDF3_MASK); 1178 if (ret) 1179 return ret; 1180 ret = mvpp2_prs_ip6_proto(sc, IPPROTO_IPIP, MVPP2_PRS_RI_UDF7_IP6_LITE, 1181 MVPP2_PRS_RI_UDF7_MASK); 1182 if (ret) 1183 return ret; 1184 ret = mvpp2_prs_ip6_cast(sc, MVPP2_PRS_L3_MULTI_CAST); 1185 if (ret) 1186 return ret; 1187 1188 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 1189 MVPP2_PE_LAST_FREE_TID); 1190 if (tid < 0) 1191 return tid; 1192 1193 memset(&pe, 0, sizeof(pe)); 1194 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6); 1195 pe.index = tid; 1196 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 1197 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 1198 mvpp2_prs_sram_ri_update(&pe, 1199 MVPP2_PRS_RI_L3_UN | MVPP2_PRS_RI_DROP_MASK, 1200 MVPP2_PRS_RI_L3_PROTO_MASK | MVPP2_PRS_RI_DROP_MASK); 1201 mvpp2_prs_tcam_data_byte_set(&pe, 1, 0x00, MVPP2_PRS_IPV6_HOP_MASK); 1202 mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, 1203 MVPP2_PRS_IPV6_NO_EXT_AI_BIT); 1204 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4); 1205 mvpp2_prs_hw_write(sc, &pe); 1206 1207 memset(&pe, 0, sizeof(pe)); 1208 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6); 1209 pe.index = MVPP2_PE_IP6_PROTO_UN; 1210 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 1211 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 1212 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER, 1213 MVPP2_PRS_RI_L4_PROTO_MASK); 1214 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4, 1215 sizeof(struct ip6_hdr) - 6, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 1216 mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, 1217 MVPP2_PRS_IPV6_NO_EXT_AI_BIT); 1218 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 1219 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4); 1220 mvpp2_prs_hw_write(sc, &pe); 1221 1222 memset(&pe, 0, sizeof(pe)); 1223 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6); 1224 pe.index = MVPP2_PE_IP6_EXT_PROTO_UN; 1225 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 1226 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 1227 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER, 1228 MVPP2_PRS_RI_L4_PROTO_MASK); 1229 mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_EXT_AI_BIT, 1230 MVPP2_PRS_IPV6_EXT_AI_BIT); 1231 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 1232 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4); 1233 mvpp2_prs_hw_write(sc, &pe); 1234 1235 memset(&pe, 0, sizeof(pe)); 1236 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6); 1237 pe.index = MVPP2_PE_IP6_ADDR_UN; 1238 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); 1239 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST, 1240 MVPP2_PRS_RI_L3_ADDR_MASK); 1241 mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, 1242 MVPP2_PRS_IPV6_NO_EXT_AI_BIT); 1243 mvpp2_prs_sram_shift_set(&pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 1244 mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT); 1245 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 1246 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP6); 1247 mvpp2_prs_hw_write(sc, &pe); 1248 1249 return 0; 1250 } 1251 1252 int 1253 mvpp2_prs_ip4_init(struct mvpp2_softc *sc) 1254 { 1255 struct mvpp2_prs_entry pe; 1256 int ret; 1257 1258 ret = mvpp2_prs_ip4_proto(sc, IPPROTO_TCP, MVPP2_PRS_RI_L4_TCP, 1259 MVPP2_PRS_RI_L4_PROTO_MASK); 1260 if (ret) 1261 return ret; 1262 ret = mvpp2_prs_ip4_proto(sc, IPPROTO_UDP, MVPP2_PRS_RI_L4_UDP, 1263 MVPP2_PRS_RI_L4_PROTO_MASK); 1264 if (ret) 1265 return ret; 1266 ret = mvpp2_prs_ip4_proto(sc, IPPROTO_IGMP, 1267 MVPP2_PRS_RI_CPU_CODE_RX_SPEC | MVPP2_PRS_RI_UDF3_RX_SPECIAL, 1268 MVPP2_PRS_RI_CPU_CODE_MASK | MVPP2_PRS_RI_UDF3_MASK); 1269 if (ret) 1270 return ret; 1271 ret = mvpp2_prs_ip4_cast(sc, MVPP2_PRS_L3_BROAD_CAST); 1272 if (ret) 1273 return ret; 1274 ret = mvpp2_prs_ip4_cast(sc, MVPP2_PRS_L3_MULTI_CAST); 1275 if (ret) 1276 return ret; 1277 1278 memset(&pe, 0, sizeof(pe)); 1279 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4); 1280 pe.index = MVPP2_PE_IP4_PROTO_UN; 1281 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4); 1282 mvpp2_prs_sram_shift_set(&pe, 12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 1283 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4, 1284 sizeof(struct ip) - 4, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 1285 mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT, 1286 MVPP2_PRS_IPV4_DIP_AI_BIT); 1287 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L4_OTHER, 1288 MVPP2_PRS_RI_L4_PROTO_MASK); 1289 mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT); 1290 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 1291 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4); 1292 mvpp2_prs_hw_write(sc, &pe); 1293 1294 memset(&pe, 0, sizeof(pe)); 1295 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4); 1296 pe.index = MVPP2_PE_IP4_ADDR_UN; 1297 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 1298 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 1299 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_UCAST, 1300 MVPP2_PRS_RI_L3_ADDR_MASK); 1301 mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT, 1302 MVPP2_PRS_IPV4_DIP_AI_BIT); 1303 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 1304 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4); 1305 mvpp2_prs_hw_write(sc, &pe); 1306 1307 return 0; 1308 } 1309 1310 int 1311 mvpp2_port_match(struct device *parent, void *cfdata, void *aux) 1312 { 1313 struct mvpp2_attach_args *maa = aux; 1314 char buf[32]; 1315 1316 if (OF_getprop(maa->ma_node, "status", buf, sizeof(buf)) > 0 && 1317 strcmp(buf, "disabled") == 0) 1318 return 0; 1319 1320 return 1; 1321 } 1322 1323 void 1324 mvpp2_port_attach(struct device *parent, struct device *self, void *aux) 1325 { 1326 struct mvpp2_port *sc = (void *)self; 1327 struct mvpp2_attach_args *maa = aux; 1328 struct mvpp2_tx_queue *txq; 1329 struct mvpp2_rx_queue *rxq; 1330 struct ifnet *ifp; 1331 uint32_t phy, reg; 1332 int i, idx, len, node; 1333 int mii_flags = 0; 1334 char *phy_mode; 1335 char *managed; 1336 1337 sc->sc = (void *)parent; 1338 sc->sc_node = maa->ma_node; 1339 sc->sc_dmat = maa->ma_dmat; 1340 1341 sc->sc_id = OF_getpropint(sc->sc_node, "port-id", 0); 1342 sc->sc_gop_id = OF_getpropint(sc->sc_node, "gop-port-id", 0); 1343 sc->sc_sfp = OF_getpropint(sc->sc_node, "sfp", 0); 1344 1345 len = OF_getproplen(sc->sc_node, "phy-mode"); 1346 if (len <= 0) { 1347 printf("%s: cannot extract phy-mode\n", self->dv_xname); 1348 return; 1349 } 1350 1351 phy_mode = malloc(len, M_TEMP, M_WAITOK); 1352 OF_getprop(sc->sc_node, "phy-mode", phy_mode, len); 1353 if (!strncmp(phy_mode, "10gbase-r", strlen("10gbase-r"))) 1354 sc->sc_phy_mode = PHY_MODE_10GBASER; 1355 else if (!strncmp(phy_mode, "10gbase-kr", strlen("10gbase-kr"))) 1356 sc->sc_phy_mode = PHY_MODE_10GBASER; 1357 else if (!strncmp(phy_mode, "2500base-x", strlen("2500base-x"))) 1358 sc->sc_phy_mode = PHY_MODE_2500BASEX; 1359 else if (!strncmp(phy_mode, "1000base-x", strlen("1000base-x"))) 1360 sc->sc_phy_mode = PHY_MODE_1000BASEX; 1361 else if (!strncmp(phy_mode, "sgmii", strlen("sgmii"))) 1362 sc->sc_phy_mode = PHY_MODE_SGMII; 1363 else if (!strncmp(phy_mode, "rgmii-rxid", strlen("rgmii-rxid"))) 1364 sc->sc_phy_mode = PHY_MODE_RGMII_RXID; 1365 else if (!strncmp(phy_mode, "rgmii-txid", strlen("rgmii-txid"))) 1366 sc->sc_phy_mode = PHY_MODE_RGMII_TXID; 1367 else if (!strncmp(phy_mode, "rgmii-id", strlen("rgmii-id"))) 1368 sc->sc_phy_mode = PHY_MODE_RGMII_ID; 1369 else if (!strncmp(phy_mode, "rgmii", strlen("rgmii"))) 1370 sc->sc_phy_mode = PHY_MODE_RGMII; 1371 else { 1372 printf("%s: cannot use phy-mode %s\n", self->dv_xname, 1373 phy_mode); 1374 return; 1375 } 1376 free(phy_mode, M_TEMP, len); 1377 1378 /* Lookup PHY. */ 1379 phy = OF_getpropint(sc->sc_node, "phy", 0); 1380 if (phy) { 1381 node = OF_getnodebyphandle(phy); 1382 if (!node) { 1383 printf(": no phy\n"); 1384 return; 1385 } 1386 sc->sc_mdio = mii_byphandle(phy); 1387 sc->sc_phyloc = OF_getpropint(node, "reg", MII_PHY_ANY); 1388 sc->sc_sfp = OF_getpropint(node, "sfp", sc->sc_sfp); 1389 sc->sc_mii.mii_node = node; 1390 } 1391 1392 if (sc->sc_sfp) 1393 config_mountroot(self, mvpp2_port_attach_sfp); 1394 1395 if ((len = OF_getproplen(sc->sc_node, "managed")) >= 0) { 1396 managed = malloc(len, M_TEMP, M_WAITOK); 1397 OF_getprop(sc->sc_node, "managed", managed, len); 1398 if (!strncmp(managed, "in-band-status", 1399 strlen("in-band-status"))) 1400 sc->sc_inband_status = 1; 1401 free(managed, M_TEMP, len); 1402 } 1403 1404 if (OF_getprop(sc->sc_node, "local-mac-address", 1405 &sc->sc_lladdr, ETHER_ADDR_LEN) != ETHER_ADDR_LEN) 1406 memset(sc->sc_lladdr, 0xff, sizeof(sc->sc_lladdr)); 1407 printf(": address %s\n", ether_sprintf(sc->sc_lladdr)); 1408 1409 sc->sc_ntxq = sc->sc_nrxq = 1; 1410 sc->sc_txqs = mallocarray(sc->sc_ntxq, sizeof(*sc->sc_txqs), 1411 M_DEVBUF, M_WAITOK | M_ZERO); 1412 sc->sc_rxqs = mallocarray(sc->sc_nrxq, sizeof(*sc->sc_rxqs), 1413 M_DEVBUF, M_WAITOK | M_ZERO); 1414 1415 for (i = 0; i < sc->sc_ntxq; i++) { 1416 txq = &sc->sc_txqs[i]; 1417 txq->id = mvpp2_txq_phys(sc->sc_id, i); 1418 txq->log_id = i; 1419 txq->done_pkts_coal = MVPP2_TXDONE_COAL_PKTS_THRESH; 1420 } 1421 1422 sc->sc_tx_time_coal = MVPP2_TXDONE_COAL_USEC; 1423 1424 for (i = 0; i < sc->sc_nrxq; i++) { 1425 rxq = &sc->sc_rxqs[i]; 1426 rxq->id = sc->sc_id * 32 + i; 1427 rxq->pkts_coal = MVPP2_RX_COAL_PKTS; 1428 rxq->time_coal = MVPP2_RX_COAL_USEC; 1429 } 1430 1431 mvpp2_egress_disable(sc); 1432 mvpp2_port_disable(sc); 1433 1434 mvpp2_write(sc->sc, MVPP2_ISR_RXQ_GROUP_INDEX_REG, 1435 sc->sc_id << MVPP2_ISR_RXQ_GROUP_INDEX_GROUP_SHIFT | 1436 0 /* queue vector id */); 1437 mvpp2_write(sc->sc, MVPP2_ISR_RXQ_SUB_GROUP_CONFIG_REG, 1438 sc->sc_nrxq << MVPP2_ISR_RXQ_SUB_GROUP_CONFIG_SIZE_SHIFT | 1439 0 /* first rxq */); 1440 1441 mvpp2_ingress_disable(sc); 1442 mvpp2_defaults_set(sc); 1443 1444 mvpp2_cls_oversize_rxq_set(sc); 1445 mvpp2_cls_port_config(sc); 1446 1447 /* 1448 * We have one pool per core, so all RX queues on a specific 1449 * core share that pool. Also long and short uses the same 1450 * pool. 1451 */ 1452 for (i = 0; i < sc->sc_nrxq; i++) { 1453 mvpp2_rxq_long_pool_set(sc, i, i); 1454 mvpp2_rxq_short_pool_set(sc, i, i); 1455 } 1456 1457 mvpp2_mac_reset_assert(sc); 1458 mvpp2_pcs_reset_assert(sc); 1459 1460 timeout_set(&sc->sc_tick, mvpp2_tick, sc); 1461 1462 ifp = &sc->sc_ac.ac_if; 1463 ifp->if_softc = sc; 1464 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 1465 ifp->if_ioctl = mvpp2_ioctl; 1466 ifp->if_start = mvpp2_start; 1467 ifp->if_watchdog = mvpp2_watchdog; 1468 ifq_init_maxlen(&ifp->if_snd, MVPP2_NTXDESC - 1); 1469 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 1470 1471 ifp->if_capabilities = IFCAP_VLAN_MTU; 1472 1473 sc->sc_mii.mii_ifp = ifp; 1474 sc->sc_mii.mii_readreg = mvpp2_mii_readreg; 1475 sc->sc_mii.mii_writereg = mvpp2_mii_writereg; 1476 sc->sc_mii.mii_statchg = mvpp2_mii_statchg; 1477 1478 ifmedia_init(&sc->sc_media, 0, mvpp2_media_change, mvpp2_media_status); 1479 1480 if (sc->sc_mdio) { 1481 switch (sc->sc_phy_mode) { 1482 case PHY_MODE_1000BASEX: 1483 mii_flags |= MIIF_IS_1000X; 1484 break; 1485 case PHY_MODE_SGMII: 1486 mii_flags |= MIIF_SGMII; 1487 break; 1488 case PHY_MODE_RGMII_ID: 1489 mii_flags |= MIIF_RXID | MIIF_TXID; 1490 break; 1491 case PHY_MODE_RGMII_RXID: 1492 mii_flags |= MIIF_RXID; 1493 break; 1494 case PHY_MODE_RGMII_TXID: 1495 mii_flags |= MIIF_TXID; 1496 break; 1497 default: 1498 break; 1499 } 1500 mii_attach(self, &sc->sc_mii, 0xffffffff, sc->sc_phyloc, 1501 (sc->sc_phyloc == MII_PHY_ANY) ? 0 : MII_OFFSET_ANY, 1502 mii_flags); 1503 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 1504 printf("%s: no PHY found!\n", self->dv_xname); 1505 ifmedia_add(&sc->sc_mii.mii_media, 1506 IFM_ETHER|IFM_MANUAL, 0, NULL); 1507 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL); 1508 } else 1509 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 1510 } else { 1511 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO, 0, NULL); 1512 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 1513 1514 if (sc->sc_inband_status) { 1515 switch (sc->sc_phy_mode) { 1516 case PHY_MODE_1000BASEX: 1517 sc->sc_mii.mii_media_active = 1518 IFM_ETHER|IFM_1000_KX|IFM_FDX; 1519 break; 1520 case PHY_MODE_2500BASEX: 1521 sc->sc_mii.mii_media_active = 1522 IFM_ETHER|IFM_2500_KX|IFM_FDX; 1523 break; 1524 case PHY_MODE_10GBASER: 1525 sc->sc_mii.mii_media_active = 1526 IFM_ETHER|IFM_10G_KR|IFM_FDX; 1527 break; 1528 default: 1529 break; 1530 } 1531 mvpp2_inband_statchg(sc); 1532 } else { 1533 sc->sc_mii.mii_media_status = IFM_AVALID|IFM_ACTIVE; 1534 sc->sc_mii.mii_media_active = IFM_ETHER|IFM_1000_T|IFM_FDX; 1535 mvpp2_mii_statchg(self); 1536 } 1537 1538 ifp->if_baudrate = ifmedia_baudrate(sc->sc_mii.mii_media_active); 1539 ifp->if_link_state = LINK_STATE_FULL_DUPLEX; 1540 } 1541 1542 if_attach(ifp); 1543 ether_ifattach(ifp); 1544 1545 if (sc->sc_phy_mode == PHY_MODE_2500BASEX || 1546 sc->sc_phy_mode == PHY_MODE_1000BASEX || 1547 sc->sc_phy_mode == PHY_MODE_SGMII || 1548 sc->sc_phy_mode == PHY_MODE_RGMII || 1549 sc->sc_phy_mode == PHY_MODE_RGMII_ID || 1550 sc->sc_phy_mode == PHY_MODE_RGMII_RXID || 1551 sc->sc_phy_mode == PHY_MODE_RGMII_TXID) { 1552 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_INT_MASK_REG); 1553 reg |= MVPP2_GMAC_INT_CAUSE_LINK_CHANGE; 1554 mvpp2_gmac_write(sc, MVPP2_GMAC_INT_MASK_REG, reg); 1555 } 1556 1557 if (sc->sc_gop_id == 0) { 1558 reg = mvpp2_xlg_read(sc, MV_XLG_INTERRUPT_MASK_REG); 1559 reg |= MV_XLG_INTERRUPT_LINK_CHANGE; 1560 mvpp2_xlg_write(sc, MV_XLG_INTERRUPT_MASK_REG, reg); 1561 } 1562 1563 mvpp2_gop_intr_unmask(sc); 1564 1565 idx = OF_getindex(sc->sc_node, "link", "interrupt-names"); 1566 if (idx >= 0) 1567 fdt_intr_establish_idx(sc->sc_node, idx, IPL_NET, 1568 mvpp2_link_intr, sc, sc->sc_dev.dv_xname); 1569 idx = OF_getindex(sc->sc_node, "hif0", "interrupt-names"); 1570 if (idx < 0) 1571 idx = OF_getindex(sc->sc_node, "tx-cpu0", "interrupt-names"); 1572 if (idx >= 0) 1573 fdt_intr_establish_idx(sc->sc_node, idx, IPL_NET, 1574 mvpp2_intr, sc, sc->sc_dev.dv_xname); 1575 } 1576 1577 void 1578 mvpp2_port_attach_sfp(struct device *self) 1579 { 1580 struct mvpp2_port *sc = (struct mvpp2_port *)self; 1581 uint32_t reg; 1582 1583 rw_enter(&mvpp2_sff_lock, RW_WRITE); 1584 sfp_disable(sc->sc_sfp); 1585 sfp_add_media(sc->sc_sfp, &sc->sc_mii); 1586 rw_exit(&mvpp2_sff_lock); 1587 1588 switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { 1589 case IFM_10G_SR: 1590 case IFM_10G_LR: 1591 case IFM_10G_LRM: 1592 case IFM_10G_ER: 1593 case IFM_10G_SFP_CU: 1594 sc->sc_phy_mode = PHY_MODE_10GBASER; 1595 sc->sc_mii.mii_media_status = IFM_AVALID; 1596 sc->sc_inband_status = 1; 1597 break; 1598 case IFM_2500_SX: 1599 sc->sc_phy_mode = PHY_MODE_2500BASEX; 1600 sc->sc_mii.mii_media_status = IFM_AVALID; 1601 sc->sc_inband_status = 1; 1602 break; 1603 case IFM_1000_CX: 1604 case IFM_1000_LX: 1605 case IFM_1000_SX: 1606 case IFM_1000_T: 1607 sc->sc_phy_mode = PHY_MODE_1000BASEX; 1608 sc->sc_mii.mii_media_status = IFM_AVALID; 1609 sc->sc_inband_status = 1; 1610 break; 1611 } 1612 1613 if (sc->sc_inband_status) { 1614 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_INT_MASK_REG); 1615 reg |= MVPP2_GMAC_INT_CAUSE_LINK_CHANGE; 1616 mvpp2_gmac_write(sc, MVPP2_GMAC_INT_MASK_REG, reg); 1617 } 1618 } 1619 1620 uint32_t 1621 mvpp2_read(struct mvpp2_softc *sc, bus_addr_t addr) 1622 { 1623 return bus_space_read_4(sc->sc_iot, sc->sc_ioh_base, addr); 1624 } 1625 1626 void 1627 mvpp2_write(struct mvpp2_softc *sc, bus_addr_t addr, uint32_t data) 1628 { 1629 bus_space_write_4(sc->sc_iot, sc->sc_ioh_base, addr, data); 1630 } 1631 1632 uint32_t 1633 mvpp2_gmac_read(struct mvpp2_port *sc, bus_addr_t addr) 1634 { 1635 return bus_space_read_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface, 1636 MVPP22_GMAC_OFFSET + sc->sc_gop_id * MVPP22_GMAC_REG_SIZE + addr); 1637 } 1638 1639 void 1640 mvpp2_gmac_write(struct mvpp2_port *sc, bus_addr_t addr, uint32_t data) 1641 { 1642 bus_space_write_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface, 1643 MVPP22_GMAC_OFFSET + sc->sc_gop_id * MVPP22_GMAC_REG_SIZE + addr, 1644 data); 1645 } 1646 1647 uint32_t 1648 mvpp2_xlg_read(struct mvpp2_port *sc, bus_addr_t addr) 1649 { 1650 return bus_space_read_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface, 1651 MVPP22_XLG_OFFSET + sc->sc_gop_id * MVPP22_XLG_REG_SIZE + addr); 1652 } 1653 1654 void 1655 mvpp2_xlg_write(struct mvpp2_port *sc, bus_addr_t addr, uint32_t data) 1656 { 1657 bus_space_write_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface, 1658 MVPP22_XLG_OFFSET + sc->sc_gop_id * MVPP22_XLG_REG_SIZE + addr, 1659 data); 1660 } 1661 1662 uint32_t 1663 mvpp2_mpcs_read(struct mvpp2_port *sc, bus_addr_t addr) 1664 { 1665 return bus_space_read_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface, 1666 MVPP22_MPCS_OFFSET + sc->sc_gop_id * MVPP22_MPCS_REG_SIZE + addr); 1667 } 1668 1669 void 1670 mvpp2_mpcs_write(struct mvpp2_port *sc, bus_addr_t addr, uint32_t data) 1671 { 1672 bus_space_write_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface, 1673 MVPP22_MPCS_OFFSET + sc->sc_gop_id * MVPP22_MPCS_REG_SIZE + addr, 1674 data); 1675 } 1676 1677 uint32_t 1678 mvpp2_xpcs_read(struct mvpp2_port *sc, bus_addr_t addr) 1679 { 1680 return bus_space_read_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface, 1681 MVPP22_XPCS_OFFSET + sc->sc_gop_id * MVPP22_XPCS_REG_SIZE + addr); 1682 } 1683 1684 void 1685 mvpp2_xpcs_write(struct mvpp2_port *sc, bus_addr_t addr, uint32_t data) 1686 { 1687 bus_space_write_4(sc->sc->sc_iot, sc->sc->sc_ioh_iface, 1688 MVPP22_XPCS_OFFSET + sc->sc_gop_id * MVPP22_XPCS_REG_SIZE + addr, 1689 data); 1690 } 1691 1692 static inline int 1693 mvpp2_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m) 1694 { 1695 int error; 1696 1697 error = bus_dmamap_load_mbuf(dmat, map, m, BUS_DMA_NOWAIT); 1698 if (error != EFBIG) 1699 return (error); 1700 1701 error = m_defrag(m, M_DONTWAIT); 1702 if (error != 0) 1703 return (error); 1704 1705 return bus_dmamap_load_mbuf(dmat, map, m, BUS_DMA_NOWAIT); 1706 } 1707 1708 void 1709 mvpp2_start(struct ifnet *ifp) 1710 { 1711 struct mvpp2_port *sc = ifp->if_softc; 1712 struct mvpp2_tx_queue *txq = &sc->sc->sc_aggr_txqs[0]; 1713 struct mvpp2_tx_desc *txd; 1714 struct mbuf *m; 1715 bus_dmamap_t map; 1716 uint32_t command; 1717 int i, current, first, last; 1718 int free, prod, used; 1719 1720 if (!(ifp->if_flags & IFF_RUNNING)) 1721 return; 1722 if (ifq_is_oactive(&ifp->if_snd)) 1723 return; 1724 if (ifq_empty(&ifp->if_snd)) 1725 return; 1726 if (!sc->sc_link) 1727 return; 1728 1729 used = 0; 1730 prod = txq->prod; 1731 free = txq->cons; 1732 if (free <= prod) 1733 free += MVPP2_AGGR_TXQ_SIZE; 1734 free -= prod; 1735 1736 for (;;) { 1737 if (free <= MVPP2_NTXSEGS) { 1738 ifq_set_oactive(&ifp->if_snd); 1739 break; 1740 } 1741 1742 m = ifq_dequeue(&ifp->if_snd); 1743 if (m == NULL) 1744 break; 1745 1746 first = last = current = prod; 1747 map = txq->buf[current].mb_map; 1748 1749 if (mvpp2_load_mbuf(sc->sc_dmat, map, m) != 0) { 1750 ifp->if_oerrors++; 1751 m_freem(m); 1752 continue; 1753 } 1754 1755 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 1756 BUS_DMASYNC_PREWRITE); 1757 1758 command = MVPP2_TXD_L4_CSUM_NOT | 1759 MVPP2_TXD_IP_CSUM_DISABLE; 1760 for (i = 0; i < map->dm_nsegs; i++) { 1761 txd = &txq->descs[current]; 1762 memset(txd, 0, sizeof(*txd)); 1763 txd->buf_phys_addr_hw_cmd2 = 1764 map->dm_segs[i].ds_addr & ~0x1f; 1765 txd->packet_offset = 1766 map->dm_segs[i].ds_addr & 0x1f; 1767 txd->data_size = map->dm_segs[i].ds_len; 1768 txd->phys_txq = sc->sc_txqs[0].id; 1769 txd->command = command | 1770 MVPP2_TXD_PADDING_DISABLE; 1771 if (i == 0) 1772 txd->command |= MVPP2_TXD_F_DESC; 1773 if (i == (map->dm_nsegs - 1)) 1774 txd->command |= MVPP2_TXD_L_DESC; 1775 1776 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(txq->ring), 1777 current * sizeof(*txd), sizeof(*txd), 1778 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1779 1780 last = current; 1781 current = (current + 1) % MVPP2_AGGR_TXQ_SIZE; 1782 KASSERT(current != txq->cons); 1783 } 1784 1785 KASSERT(txq->buf[last].mb_m == NULL); 1786 txq->buf[first].mb_map = txq->buf[last].mb_map; 1787 txq->buf[last].mb_map = map; 1788 txq->buf[last].mb_m = m; 1789 1790 #if NBPFILTER > 0 1791 if (ifp->if_bpf) 1792 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 1793 #endif 1794 1795 free -= map->dm_nsegs; 1796 used += map->dm_nsegs; 1797 prod = current; 1798 } 1799 1800 if (used) 1801 mvpp2_write(sc->sc, MVPP2_AGGR_TXQ_UPDATE_REG, used); 1802 1803 if (txq->prod != prod) 1804 txq->prod = prod; 1805 } 1806 1807 int 1808 mvpp2_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) 1809 { 1810 struct mvpp2_port *sc = ifp->if_softc; 1811 struct ifreq *ifr = (struct ifreq *)addr; 1812 int error = 0, s; 1813 1814 s = splnet(); 1815 1816 switch (cmd) { 1817 case SIOCSIFADDR: 1818 ifp->if_flags |= IFF_UP; 1819 /* FALLTHROUGH */ 1820 case SIOCSIFFLAGS: 1821 if (ifp->if_flags & IFF_UP) { 1822 if (ifp->if_flags & IFF_RUNNING) 1823 error = ENETRESET; 1824 else 1825 mvpp2_up(sc); 1826 } else { 1827 if (ifp->if_flags & IFF_RUNNING) 1828 mvpp2_down(sc); 1829 } 1830 break; 1831 1832 case SIOCGIFMEDIA: 1833 case SIOCSIFMEDIA: 1834 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 1835 break; 1836 1837 case SIOCGIFRXR: 1838 error = mvpp2_rxrinfo(sc, (struct if_rxrinfo *)ifr->ifr_data); 1839 break; 1840 1841 case SIOCGIFSFFPAGE: 1842 error = rw_enter(&mvpp2_sff_lock, RW_WRITE|RW_INTR); 1843 if (error != 0) 1844 break; 1845 1846 error = sfp_get_sffpage(sc->sc_sfp, (struct if_sffpage *)addr); 1847 rw_exit(&mvpp2_sff_lock); 1848 break; 1849 1850 default: 1851 error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr); 1852 break; 1853 } 1854 1855 if (error == ENETRESET) { 1856 if (ifp->if_flags & IFF_RUNNING) 1857 mvpp2_iff(sc); 1858 error = 0; 1859 } 1860 1861 splx(s); 1862 return (error); 1863 } 1864 1865 int 1866 mvpp2_rxrinfo(struct mvpp2_port *sc, struct if_rxrinfo *ifri) 1867 { 1868 struct mvpp2_rx_queue *rxq; 1869 struct if_rxring_info *ifrs, *ifr; 1870 unsigned int i; 1871 int error; 1872 1873 ifrs = mallocarray(sc->sc_nrxq, sizeof(*ifrs), M_TEMP, 1874 M_WAITOK|M_ZERO|M_CANFAIL); 1875 if (ifrs == NULL) 1876 return (ENOMEM); 1877 1878 for (i = 0; i < sc->sc_nrxq; i++) { 1879 rxq = &sc->sc_rxqs[i]; 1880 ifr = &ifrs[i]; 1881 1882 snprintf(ifr->ifr_name, sizeof(ifr->ifr_name), "%u", i); 1883 ifr->ifr_size = MCLBYTES; 1884 ifr->ifr_info = rxq->rxring; 1885 } 1886 1887 error = if_rxr_info_ioctl(ifri, i, ifrs); 1888 free(ifrs, M_TEMP, i * sizeof(*ifrs)); 1889 1890 return (error); 1891 } 1892 1893 void 1894 mvpp2_watchdog(struct ifnet *ifp) 1895 { 1896 printf("%s\n", __func__); 1897 } 1898 1899 int 1900 mvpp2_media_change(struct ifnet *ifp) 1901 { 1902 struct mvpp2_port *sc = ifp->if_softc; 1903 1904 if (LIST_FIRST(&sc->sc_mii.mii_phys)) 1905 mii_mediachg(&sc->sc_mii); 1906 1907 return (0); 1908 } 1909 1910 void 1911 mvpp2_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) 1912 { 1913 struct mvpp2_port *sc = ifp->if_softc; 1914 1915 if (LIST_FIRST(&sc->sc_mii.mii_phys)) 1916 mii_pollstat(&sc->sc_mii); 1917 1918 ifmr->ifm_active = sc->sc_mii.mii_media_active; 1919 ifmr->ifm_status = sc->sc_mii.mii_media_status; 1920 } 1921 1922 int 1923 mvpp2_mii_readreg(struct device *self, int phy, int reg) 1924 { 1925 struct mvpp2_port *sc = (void *)self; 1926 return sc->sc_mdio->md_readreg(sc->sc_mdio->md_cookie, phy, reg); 1927 } 1928 1929 void 1930 mvpp2_mii_writereg(struct device *self, int phy, int reg, int val) 1931 { 1932 struct mvpp2_port *sc = (void *)self; 1933 return sc->sc_mdio->md_writereg(sc->sc_mdio->md_cookie, phy, reg, val); 1934 } 1935 1936 void 1937 mvpp2_mii_statchg(struct device *self) 1938 { 1939 struct mvpp2_port *sc = (void *)self; 1940 mvpp2_port_change(sc); 1941 } 1942 1943 void 1944 mvpp2_inband_statchg(struct mvpp2_port *sc) 1945 { 1946 uint64_t subtype = IFM_SUBTYPE(sc->sc_mii.mii_media_active); 1947 uint32_t reg; 1948 1949 sc->sc_mii.mii_media_status = IFM_AVALID; 1950 sc->sc_mii.mii_media_active = IFM_ETHER; 1951 1952 if (sc->sc_gop_id == 0 && (sc->sc_phy_mode == PHY_MODE_10GBASER || 1953 sc->sc_phy_mode == PHY_MODE_XAUI)) { 1954 reg = mvpp2_xlg_read(sc, MV_XLG_MAC_PORT_STATUS_REG); 1955 if (reg & MV_XLG_MAC_PORT_STATUS_LINKSTATUS) 1956 sc->sc_mii.mii_media_status |= IFM_ACTIVE; 1957 sc->sc_mii.mii_media_active |= IFM_FDX; 1958 sc->sc_mii.mii_media_active |= subtype; 1959 } else { 1960 reg = mvpp2_gmac_read(sc, MVPP2_PORT_STATUS0_REG); 1961 if (reg & MVPP2_PORT_STATUS0_LINKUP) 1962 sc->sc_mii.mii_media_status |= IFM_ACTIVE; 1963 if (reg & MVPP2_PORT_STATUS0_FULLDX) 1964 sc->sc_mii.mii_media_active |= IFM_FDX; 1965 if (sc->sc_phy_mode == PHY_MODE_2500BASEX) 1966 sc->sc_mii.mii_media_active |= subtype; 1967 else if (sc->sc_phy_mode == PHY_MODE_1000BASEX) 1968 sc->sc_mii.mii_media_active |= subtype; 1969 else if (reg & MVPP2_PORT_STATUS0_GMIISPEED) 1970 sc->sc_mii.mii_media_active |= IFM_1000_T; 1971 else if (reg & MVPP2_PORT_STATUS0_MIISPEED) 1972 sc->sc_mii.mii_media_active |= IFM_100_TX; 1973 else 1974 sc->sc_mii.mii_media_active |= IFM_10_T; 1975 } 1976 1977 mvpp2_port_change(sc); 1978 } 1979 1980 void 1981 mvpp2_port_change(struct mvpp2_port *sc) 1982 { 1983 uint32_t reg; 1984 1985 sc->sc_link = !!(sc->sc_mii.mii_media_status & IFM_ACTIVE); 1986 1987 if (sc->sc_inband_status) 1988 return; 1989 1990 if (sc->sc_link) { 1991 if (sc->sc_phy_mode == PHY_MODE_10GBASER || 1992 sc->sc_phy_mode == PHY_MODE_XAUI) { 1993 reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG); 1994 reg &= ~MV_XLG_MAC_CTRL0_FORCELINKDOWN; 1995 reg |= MV_XLG_MAC_CTRL0_FORCELINKPASS; 1996 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, reg); 1997 } else { 1998 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_AUTONEG_CONFIG); 1999 reg &= ~MVPP2_GMAC_FORCE_LINK_DOWN; 2000 reg |= MVPP2_GMAC_FORCE_LINK_PASS; 2001 reg &= ~MVPP2_GMAC_CONFIG_MII_SPEED; 2002 reg &= ~MVPP2_GMAC_CONFIG_GMII_SPEED; 2003 reg &= ~MVPP2_GMAC_CONFIG_FULL_DUPLEX; 2004 if (IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_2500_KX || 2005 IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_2500_SX || 2006 IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_1000_CX || 2007 IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_1000_LX || 2008 IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_1000_KX || 2009 IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_1000_SX || 2010 IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_1000_T) 2011 reg |= MVPP2_GMAC_CONFIG_GMII_SPEED; 2012 if (IFM_SUBTYPE(sc->sc_mii.mii_media_active) == IFM_100_TX) 2013 reg |= MVPP2_GMAC_CONFIG_MII_SPEED; 2014 if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX) 2015 reg |= MVPP2_GMAC_CONFIG_FULL_DUPLEX; 2016 mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, reg); 2017 } 2018 } else { 2019 if (sc->sc_phy_mode == PHY_MODE_10GBASER || 2020 sc->sc_phy_mode == PHY_MODE_XAUI) { 2021 reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG); 2022 reg &= ~MV_XLG_MAC_CTRL0_FORCELINKPASS; 2023 reg |= MV_XLG_MAC_CTRL0_FORCELINKDOWN; 2024 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, reg); 2025 } else { 2026 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_AUTONEG_CONFIG); 2027 reg &= ~MVPP2_GMAC_FORCE_LINK_PASS; 2028 reg |= MVPP2_GMAC_FORCE_LINK_DOWN; 2029 mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, reg); 2030 } 2031 } 2032 } 2033 2034 void 2035 mvpp2_tick(void *arg) 2036 { 2037 struct mvpp2_port *sc = arg; 2038 int s; 2039 2040 s = splnet(); 2041 mii_tick(&sc->sc_mii); 2042 splx(s); 2043 2044 timeout_add_sec(&sc->sc_tick, 1); 2045 } 2046 2047 int 2048 mvpp2_link_intr(void *arg) 2049 { 2050 struct mvpp2_port *sc = arg; 2051 uint32_t reg; 2052 int event = 0; 2053 2054 if (sc->sc_gop_id == 0 && (sc->sc_phy_mode == PHY_MODE_10GBASER || 2055 sc->sc_phy_mode == PHY_MODE_XAUI)) { 2056 reg = mvpp2_xlg_read(sc, MV_XLG_INTERRUPT_CAUSE_REG); 2057 if (reg & MV_XLG_INTERRUPT_LINK_CHANGE) 2058 event = 1; 2059 } else if (sc->sc_phy_mode == PHY_MODE_2500BASEX || 2060 sc->sc_phy_mode == PHY_MODE_1000BASEX || 2061 sc->sc_phy_mode == PHY_MODE_SGMII || 2062 sc->sc_phy_mode == PHY_MODE_RGMII || 2063 sc->sc_phy_mode == PHY_MODE_RGMII_ID || 2064 sc->sc_phy_mode == PHY_MODE_RGMII_RXID || 2065 sc->sc_phy_mode == PHY_MODE_RGMII_TXID) { 2066 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_INT_CAUSE_REG); 2067 if (reg & MVPP2_GMAC_INT_CAUSE_LINK_CHANGE) 2068 event = 1; 2069 } 2070 2071 if (event && sc->sc_inband_status) 2072 mvpp2_inband_statchg(sc); 2073 2074 return (1); 2075 } 2076 2077 int 2078 mvpp2_intr(void *arg) 2079 { 2080 struct mvpp2_port *sc = arg; 2081 uint32_t reg; 2082 2083 reg = mvpp2_read(sc->sc, MVPP2_ISR_RX_TX_CAUSE_REG(sc->sc_id)); 2084 if (reg & MVPP2_CAUSE_MISC_SUM_MASK) { 2085 mvpp2_write(sc->sc, MVPP2_ISR_MISC_CAUSE_REG, 0); 2086 mvpp2_write(sc->sc, MVPP2_ISR_RX_TX_CAUSE_REG(sc->sc_id), 2087 reg & ~MVPP2_CAUSE_MISC_SUM_MASK); 2088 } 2089 if (reg & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK) 2090 mvpp2_tx_proc(sc, 2091 (reg & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK) >> 2092 MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET); 2093 2094 if (reg & MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK) 2095 mvpp2_rx_proc(sc, 2096 reg & MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK); 2097 2098 return (1); 2099 } 2100 2101 void 2102 mvpp2_tx_proc(struct mvpp2_port *sc, uint8_t queues) 2103 { 2104 struct mvpp2_tx_queue *txq; 2105 int i; 2106 2107 for (i = 0; i < sc->sc_ntxq; i++) { 2108 txq = &sc->sc_txqs[i]; 2109 if ((queues & (1 << i)) == 0) 2110 continue; 2111 mvpp2_txq_proc(sc, txq); 2112 } 2113 } 2114 2115 void 2116 mvpp2_txq_proc(struct mvpp2_port *sc, struct mvpp2_tx_queue *txq) 2117 { 2118 struct ifnet *ifp = &sc->sc_ac.ac_if; 2119 struct mvpp2_tx_queue *aggr_txq = &sc->sc->sc_aggr_txqs[0]; 2120 struct mvpp2_buf *txb; 2121 int i, idx, nsent; 2122 2123 /* XXX: this is a percpu register! */ 2124 nsent = (mvpp2_read(sc->sc, MVPP2_TXQ_SENT_REG(txq->id)) & 2125 MVPP2_TRANSMITTED_COUNT_MASK) >> 2126 MVPP2_TRANSMITTED_COUNT_OFFSET; 2127 2128 for (i = 0; i < nsent; i++) { 2129 idx = aggr_txq->cons; 2130 KASSERT(idx < MVPP2_AGGR_TXQ_SIZE); 2131 2132 txb = &aggr_txq->buf[idx]; 2133 if (txb->mb_m) { 2134 bus_dmamap_sync(sc->sc_dmat, txb->mb_map, 0, 2135 txb->mb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 2136 bus_dmamap_unload(sc->sc_dmat, txb->mb_map); 2137 2138 m_freem(txb->mb_m); 2139 txb->mb_m = NULL; 2140 } 2141 2142 aggr_txq->cons = (aggr_txq->cons + 1) % MVPP2_AGGR_TXQ_SIZE; 2143 } 2144 2145 if (ifq_is_oactive(&ifp->if_snd)) 2146 ifq_restart(&ifp->if_snd); 2147 } 2148 2149 void 2150 mvpp2_rx_proc(struct mvpp2_port *sc, uint8_t queues) 2151 { 2152 struct mvpp2_rx_queue *rxq; 2153 int i; 2154 2155 for (i = 0; i < sc->sc_nrxq; i++) { 2156 rxq = &sc->sc_rxqs[i]; 2157 if ((queues & (1 << i)) == 0) 2158 continue; 2159 mvpp2_rxq_proc(sc, rxq); 2160 } 2161 2162 mvpp2_rx_refill(sc); 2163 } 2164 2165 void 2166 mvpp2_rxq_proc(struct mvpp2_port *sc, struct mvpp2_rx_queue *rxq) 2167 { 2168 struct ifnet *ifp = &sc->sc_ac.ac_if; 2169 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 2170 struct mvpp2_rx_desc *rxd; 2171 struct mvpp2_bm_pool *bm; 2172 struct mvpp2_buf *rxb; 2173 struct mbuf *m; 2174 uint64_t virt; 2175 uint32_t i, nrecv, pool; 2176 2177 nrecv = mvpp2_rxq_received(sc, rxq->id); 2178 if (!nrecv) 2179 return; 2180 2181 pool = curcpu()->ci_cpuid; 2182 KASSERT(pool < sc->sc->sc_npools); 2183 bm = &sc->sc->sc_bm_pools[pool]; 2184 2185 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(rxq->ring), 0, 2186 MVPP2_DMA_LEN(rxq->ring), 2187 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2188 2189 for (i = 0; i < nrecv; i++) { 2190 rxd = &rxq->descs[rxq->cons]; 2191 virt = rxd->buf_cookie_bm_qset_cls_info; 2192 KASSERT(((virt >> 16) & 0xffff) == pool); 2193 KASSERT((virt & 0xffff) < MVPP2_BM_SIZE); 2194 rxb = &bm->rxbuf[virt & 0xffff]; 2195 KASSERT(rxb->mb_m != NULL); 2196 2197 bus_dmamap_sync(sc->sc_dmat, rxb->mb_map, 0, 2198 rxd->data_size, BUS_DMASYNC_POSTREAD); 2199 bus_dmamap_unload(sc->sc_dmat, rxb->mb_map); 2200 2201 m = rxb->mb_m; 2202 rxb->mb_m = NULL; 2203 2204 m->m_pkthdr.len = m->m_len = rxd->data_size; 2205 m_adj(m, MVPP2_MH_SIZE); 2206 ml_enqueue(&ml, m); 2207 2208 KASSERT(bm->freelist[bm->free_prod] == -1); 2209 bm->freelist[bm->free_prod] = virt & 0xffffffff; 2210 bm->free_prod = (bm->free_prod + 1) % MVPP2_BM_SIZE; 2211 2212 rxq->cons = (rxq->cons + 1) % MVPP2_NRXDESC; 2213 } 2214 2215 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(rxq->ring), 0, 2216 MVPP2_DMA_LEN(rxq->ring), 2217 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 2218 2219 mvpp2_rxq_status_update(sc, rxq->id, nrecv, nrecv); 2220 2221 if_input(ifp, &ml); 2222 } 2223 2224 /* 2225 * We have a pool per core, and since we should not assume that 2226 * RX buffers are always used in order, keep a list of rxbuf[] 2227 * indices that should be filled with an mbuf, if possible. 2228 */ 2229 void 2230 mvpp2_rx_refill(struct mvpp2_port *sc) 2231 { 2232 struct mvpp2_bm_pool *bm; 2233 struct mvpp2_buf *rxb; 2234 uint64_t phys, virt; 2235 int pool; 2236 2237 pool = curcpu()->ci_cpuid; 2238 KASSERT(pool < sc->sc->sc_npools); 2239 bm = &sc->sc->sc_bm_pools[pool]; 2240 2241 while (bm->freelist[bm->free_cons] != -1) { 2242 virt = bm->freelist[bm->free_cons]; 2243 KASSERT(((virt >> 16) & 0xffff) == pool); 2244 KASSERT((virt & 0xffff) < MVPP2_BM_SIZE); 2245 rxb = &bm->rxbuf[virt & 0xffff]; 2246 KASSERT(rxb->mb_m == NULL); 2247 2248 rxb->mb_m = mvpp2_alloc_mbuf(sc->sc, rxb->mb_map); 2249 if (rxb->mb_m == NULL) 2250 break; 2251 2252 bm->freelist[bm->free_cons] = -1; 2253 bm->free_cons = (bm->free_cons + 1) % MVPP2_BM_SIZE; 2254 2255 phys = rxb->mb_map->dm_segs[0].ds_addr; 2256 mvpp2_write(sc->sc, MVPP22_BM_ADDR_HIGH_RLS_REG, 2257 (((virt >> 32) & MVPP22_ADDR_HIGH_MASK) 2258 << MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT) | 2259 ((phys >> 32) & MVPP22_ADDR_HIGH_MASK)); 2260 mvpp2_write(sc->sc, MVPP2_BM_VIRT_RLS_REG, 2261 virt & 0xffffffff); 2262 mvpp2_write(sc->sc, MVPP2_BM_PHY_RLS_REG(pool), 2263 phys & 0xffffffff); 2264 } 2265 } 2266 2267 void 2268 mvpp2_up(struct mvpp2_port *sc) 2269 { 2270 struct ifnet *ifp = &sc->sc_ac.ac_if; 2271 int i; 2272 2273 if (sc->sc_sfp) { 2274 rw_enter(&mvpp2_sff_lock, RW_WRITE); 2275 sfp_enable(sc->sc_sfp); 2276 rw_exit(&mvpp2_sff_lock); 2277 } 2278 2279 mvpp2_prs_mac_da_accept(sc, etherbroadcastaddr, 1); 2280 mvpp2_prs_mac_da_accept(sc, sc->sc_lladdr, 1); 2281 mvpp2_prs_tag_mode_set(sc->sc, sc->sc_id, MVPP2_TAG_TYPE_MH); 2282 mvpp2_prs_def_flow(sc); 2283 2284 for (i = 0; i < sc->sc_ntxq; i++) 2285 mvpp2_txq_hw_init(sc, &sc->sc_txqs[i]); 2286 2287 mvpp2_tx_time_coal_set(sc, sc->sc_tx_time_coal); 2288 2289 for (i = 0; i < sc->sc_nrxq; i++) 2290 mvpp2_rxq_hw_init(sc, &sc->sc_rxqs[i]); 2291 2292 /* FIXME: rx buffer fill */ 2293 2294 /* Configure media. */ 2295 if (LIST_FIRST(&sc->sc_mii.mii_phys)) 2296 mii_mediachg(&sc->sc_mii); 2297 2298 /* Program promiscuous mode and multicast filters. */ 2299 mvpp2_iff(sc); 2300 2301 ifp->if_flags |= IFF_RUNNING; 2302 ifq_clr_oactive(&ifp->if_snd); 2303 2304 mvpp2_txp_max_tx_size_set(sc); 2305 2306 /* XXX: single vector */ 2307 mvpp2_write(sc->sc, MVPP2_ISR_RX_TX_MASK_REG(sc->sc_id), 2308 MVPP2_CAUSE_RXQ_OCCUP_DESC_ALL_MASK | 2309 MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK | 2310 MVPP2_CAUSE_MISC_SUM_MASK); 2311 mvpp2_interrupts_enable(sc, (1 << 0)); 2312 2313 mvpp2_mac_config(sc); 2314 mvpp2_egress_enable(sc); 2315 mvpp2_ingress_enable(sc); 2316 2317 timeout_add_sec(&sc->sc_tick, 1); 2318 } 2319 2320 void 2321 mvpp2_aggr_txq_hw_init(struct mvpp2_softc *sc, struct mvpp2_tx_queue *txq) 2322 { 2323 struct mvpp2_buf *txb; 2324 int i; 2325 2326 txq->ring = mvpp2_dmamem_alloc(sc, 2327 MVPP2_AGGR_TXQ_SIZE * sizeof(struct mvpp2_tx_desc), 32); 2328 KASSERT(txq->ring != NULL); 2329 txq->descs = MVPP2_DMA_KVA(txq->ring); 2330 2331 txq->buf = mallocarray(MVPP2_AGGR_TXQ_SIZE, sizeof(struct mvpp2_buf), 2332 M_DEVBUF, M_WAITOK); 2333 2334 for (i = 0; i < MVPP2_AGGR_TXQ_SIZE; i++) { 2335 txb = &txq->buf[i]; 2336 bus_dmamap_create(sc->sc_dmat, MCLBYTES, MVPP2_NTXSEGS, 2337 MCLBYTES, 0, BUS_DMA_WAITOK, &txb->mb_map); 2338 txb->mb_m = NULL; 2339 } 2340 2341 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(txq->ring), 0, 2342 MVPP2_DMA_LEN(txq->ring), BUS_DMASYNC_PREWRITE); 2343 2344 txq->prod = mvpp2_read(sc, MVPP2_AGGR_TXQ_INDEX_REG(txq->id)); 2345 mvpp2_write(sc, MVPP2_AGGR_TXQ_DESC_ADDR_REG(txq->id), 2346 MVPP2_DMA_DVA(txq->ring) >> MVPP22_DESC_ADDR_OFFS); 2347 mvpp2_write(sc, MVPP2_AGGR_TXQ_DESC_SIZE_REG(txq->id), 2348 MVPP2_AGGR_TXQ_SIZE); 2349 } 2350 2351 void 2352 mvpp2_txq_hw_init(struct mvpp2_port *sc, struct mvpp2_tx_queue *txq) 2353 { 2354 struct mvpp2_buf *txb; 2355 int desc, desc_per_txq; 2356 uint32_t reg; 2357 int i; 2358 2359 txq->prod = txq->cons = 0; 2360 // txq->last_desc = txq->size - 1; 2361 2362 txq->ring = mvpp2_dmamem_alloc(sc->sc, 2363 MVPP2_NTXDESC * sizeof(struct mvpp2_tx_desc), 32); 2364 KASSERT(txq->ring != NULL); 2365 txq->descs = MVPP2_DMA_KVA(txq->ring); 2366 2367 txq->buf = mallocarray(MVPP2_NTXDESC, sizeof(struct mvpp2_buf), 2368 M_DEVBUF, M_WAITOK); 2369 2370 for (i = 0; i < MVPP2_NTXDESC; i++) { 2371 txb = &txq->buf[i]; 2372 bus_dmamap_create(sc->sc_dmat, MCLBYTES, MVPP2_NTXSEGS, 2373 MCLBYTES, 0, BUS_DMA_WAITOK, &txb->mb_map); 2374 txb->mb_m = NULL; 2375 } 2376 2377 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(txq->ring), 0, 2378 MVPP2_DMA_LEN(txq->ring), BUS_DMASYNC_PREWRITE); 2379 2380 mvpp2_write(sc->sc, MVPP2_TXQ_NUM_REG, txq->id); 2381 mvpp2_write(sc->sc, MVPP2_TXQ_DESC_ADDR_REG, 2382 MVPP2_DMA_DVA(txq->ring)); 2383 mvpp2_write(sc->sc, MVPP2_TXQ_DESC_SIZE_REG, 2384 MVPP2_NTXDESC & MVPP2_TXQ_DESC_SIZE_MASK); 2385 mvpp2_write(sc->sc, MVPP2_TXQ_INDEX_REG, 0); 2386 mvpp2_write(sc->sc, MVPP2_TXQ_RSVD_CLR_REG, 2387 txq->id << MVPP2_TXQ_RSVD_CLR_OFFSET); 2388 reg = mvpp2_read(sc->sc, MVPP2_TXQ_PENDING_REG); 2389 reg &= ~MVPP2_TXQ_PENDING_MASK; 2390 mvpp2_write(sc->sc, MVPP2_TXQ_PENDING_REG, reg); 2391 2392 desc_per_txq = 16; 2393 desc = (sc->sc_id * MVPP2_MAX_TXQ * desc_per_txq) + 2394 (txq->log_id * desc_per_txq); 2395 2396 mvpp2_write(sc->sc, MVPP2_TXQ_PREF_BUF_REG, 2397 MVPP2_PREF_BUF_PTR(desc) | MVPP2_PREF_BUF_SIZE_16 | 2398 MVPP2_PREF_BUF_THRESH(desc_per_txq / 2)); 2399 2400 /* WRR / EJP configuration - indirect access */ 2401 mvpp2_write(sc->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG, 2402 mvpp2_egress_port(sc)); 2403 2404 reg = mvpp2_read(sc->sc, MVPP2_TXQ_SCHED_REFILL_REG(txq->log_id)); 2405 reg &= ~MVPP2_TXQ_REFILL_PERIOD_ALL_MASK; 2406 reg |= MVPP2_TXQ_REFILL_PERIOD_MASK(1); 2407 reg |= MVPP2_TXQ_REFILL_TOKENS_ALL_MASK; 2408 mvpp2_write(sc->sc, MVPP2_TXQ_SCHED_REFILL_REG(txq->log_id), reg); 2409 2410 mvpp2_write(sc->sc, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq->log_id), 2411 MVPP2_TXQ_TOKEN_SIZE_MAX); 2412 2413 mvpp2_tx_pkts_coal_set(sc, txq, txq->done_pkts_coal); 2414 2415 mvpp2_read(sc->sc, MVPP2_TXQ_SENT_REG(txq->id)); 2416 } 2417 2418 void 2419 mvpp2_rxq_hw_init(struct mvpp2_port *sc, struct mvpp2_rx_queue *rxq) 2420 { 2421 rxq->prod = rxq->cons = 0; 2422 2423 rxq->ring = mvpp2_dmamem_alloc(sc->sc, 2424 MVPP2_NRXDESC * sizeof(struct mvpp2_rx_desc), 32); 2425 KASSERT(rxq->ring != NULL); 2426 rxq->descs = MVPP2_DMA_KVA(rxq->ring); 2427 2428 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(rxq->ring), 2429 0, MVPP2_DMA_LEN(rxq->ring), 2430 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 2431 2432 mvpp2_write(sc->sc, MVPP2_RXQ_STATUS_REG(rxq->id), 0); 2433 mvpp2_write(sc->sc, MVPP2_RXQ_NUM_REG, rxq->id); 2434 mvpp2_write(sc->sc, MVPP2_RXQ_DESC_ADDR_REG, 2435 MVPP2_DMA_DVA(rxq->ring) >> MVPP22_DESC_ADDR_OFFS); 2436 mvpp2_write(sc->sc, MVPP2_RXQ_DESC_SIZE_REG, MVPP2_NRXDESC); 2437 mvpp2_write(sc->sc, MVPP2_RXQ_INDEX_REG, 0); 2438 mvpp2_rxq_offset_set(sc, rxq->id, 0); 2439 mvpp2_rx_pkts_coal_set(sc, rxq, rxq->pkts_coal); 2440 mvpp2_rx_time_coal_set(sc, rxq, rxq->time_coal); 2441 mvpp2_rxq_status_update(sc, rxq->id, 0, MVPP2_NRXDESC); 2442 } 2443 2444 void 2445 mvpp2_mac_reset_assert(struct mvpp2_port *sc) 2446 { 2447 mvpp2_gmac_write(sc, MVPP2_PORT_CTRL2_REG, 2448 mvpp2_gmac_read(sc, MVPP2_PORT_CTRL2_REG) | 2449 MVPP2_PORT_CTRL2_PORTMACRESET); 2450 if (sc->sc_gop_id == 0) 2451 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, 2452 mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG) & 2453 ~MV_XLG_MAC_CTRL0_MACRESETN); 2454 } 2455 2456 void 2457 mvpp2_pcs_reset_assert(struct mvpp2_port *sc) 2458 { 2459 uint32_t reg; 2460 2461 if (sc->sc_gop_id != 0) 2462 return; 2463 2464 reg = mvpp2_mpcs_read(sc, MVPP22_MPCS_CLOCK_RESET); 2465 reg |= MVPP22_MPCS_CLK_DIV_PHASE_SET; 2466 reg &= ~MVPP22_MPCS_TX_SD_CLK_RESET; 2467 reg &= ~MVPP22_MPCS_RX_SD_CLK_RESET; 2468 reg &= ~MVPP22_MPCS_MAC_CLK_RESET; 2469 mvpp2_mpcs_write(sc, MVPP22_MPCS_CLOCK_RESET, reg); 2470 reg = mvpp2_xpcs_read(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG); 2471 reg &= ~MVPP22_XPCS_PCSRESET; 2472 mvpp2_xpcs_write(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG, reg); 2473 } 2474 2475 void 2476 mvpp2_pcs_reset_deassert(struct mvpp2_port *sc) 2477 { 2478 uint32_t reg; 2479 2480 if (sc->sc_gop_id != 0) 2481 return; 2482 2483 if (sc->sc_phy_mode == PHY_MODE_10GBASER) { 2484 reg = mvpp2_mpcs_read(sc, MVPP22_MPCS_CLOCK_RESET); 2485 reg &= ~MVPP22_MPCS_CLK_DIV_PHASE_SET; 2486 reg |= MVPP22_MPCS_TX_SD_CLK_RESET; 2487 reg |= MVPP22_MPCS_RX_SD_CLK_RESET; 2488 reg |= MVPP22_MPCS_MAC_CLK_RESET; 2489 mvpp2_mpcs_write(sc, MVPP22_MPCS_CLOCK_RESET, reg); 2490 } else if (sc->sc_phy_mode == PHY_MODE_XAUI) { 2491 reg = mvpp2_xpcs_read(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG); 2492 reg |= MVPP22_XPCS_PCSRESET; 2493 mvpp2_xpcs_write(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG, reg); 2494 } 2495 } 2496 2497 void 2498 mvpp2_mac_config(struct mvpp2_port *sc) 2499 { 2500 uint32_t reg; 2501 2502 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_AUTONEG_CONFIG); 2503 reg &= ~MVPP2_GMAC_FORCE_LINK_PASS; 2504 reg |= MVPP2_GMAC_FORCE_LINK_DOWN; 2505 mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, reg); 2506 if (sc->sc_gop_id == 0) { 2507 reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG); 2508 reg &= ~MV_XLG_MAC_CTRL0_FORCELINKPASS; 2509 reg |= MV_XLG_MAC_CTRL0_FORCELINKDOWN; 2510 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, reg); 2511 } 2512 2513 mvpp2_port_disable(sc); 2514 2515 mvpp2_mac_reset_assert(sc); 2516 mvpp2_pcs_reset_assert(sc); 2517 2518 mvpp2_gop_intr_mask(sc); 2519 mvpp2_comphy_config(sc, 0); 2520 2521 if (sc->sc_gop_id == 0 && (sc->sc_phy_mode == PHY_MODE_10GBASER || 2522 sc->sc_phy_mode == PHY_MODE_XAUI)) 2523 mvpp2_xlg_config(sc); 2524 else 2525 mvpp2_gmac_config(sc); 2526 2527 mvpp2_comphy_config(sc, 1); 2528 mvpp2_gop_config(sc); 2529 2530 mvpp2_pcs_reset_deassert(sc); 2531 2532 if (sc->sc_gop_id == 0) { 2533 reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL3_REG); 2534 reg &= ~MV_XLG_MAC_CTRL3_MACMODESELECT_MASK; 2535 if (sc->sc_phy_mode == PHY_MODE_10GBASER || 2536 sc->sc_phy_mode == PHY_MODE_XAUI) 2537 reg |= MV_XLG_MAC_CTRL3_MACMODESELECT_10G; 2538 else 2539 reg |= MV_XLG_MAC_CTRL3_MACMODESELECT_GMAC; 2540 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL3_REG, reg); 2541 } 2542 2543 if (sc->sc_gop_id == 0 && (sc->sc_phy_mode == PHY_MODE_10GBASER || 2544 sc->sc_phy_mode == PHY_MODE_XAUI)) { 2545 reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL1_REG); 2546 reg &= ~MV_XLG_MAC_CTRL1_FRAMESIZELIMIT_MASK; 2547 reg |= ((MCLBYTES - MVPP2_MH_SIZE) / 2) << 2548 MV_XLG_MAC_CTRL1_FRAMESIZELIMIT_OFFS; 2549 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL1_REG, reg); 2550 } else { 2551 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_CTRL_0_REG); 2552 reg &= ~MVPP2_GMAC_MAX_RX_SIZE_MASK; 2553 reg |= ((MCLBYTES - MVPP2_MH_SIZE) / 2) << 2554 MVPP2_GMAC_MAX_RX_SIZE_OFFS; 2555 mvpp2_gmac_write(sc, MVPP2_GMAC_CTRL_0_REG, reg); 2556 } 2557 2558 mvpp2_gop_intr_unmask(sc); 2559 2560 if (!(sc->sc_phy_mode == PHY_MODE_10GBASER || 2561 sc->sc_phy_mode == PHY_MODE_XAUI)) { 2562 mvpp2_gmac_write(sc, MVPP2_PORT_CTRL2_REG, 2563 mvpp2_gmac_read(sc, MVPP2_PORT_CTRL2_REG) & 2564 ~MVPP2_PORT_CTRL2_PORTMACRESET); 2565 while (mvpp2_gmac_read(sc, MVPP2_PORT_CTRL2_REG) & 2566 MVPP2_PORT_CTRL2_PORTMACRESET) 2567 ; 2568 } 2569 2570 mvpp2_port_enable(sc); 2571 2572 if (sc->sc_inband_status) { 2573 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_AUTONEG_CONFIG); 2574 reg &= ~MVPP2_GMAC_FORCE_LINK_PASS; 2575 reg &= ~MVPP2_GMAC_FORCE_LINK_DOWN; 2576 mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, reg); 2577 if (sc->sc_gop_id == 0) { 2578 reg = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG); 2579 reg &= ~MV_XLG_MAC_CTRL0_FORCELINKPASS; 2580 reg &= ~MV_XLG_MAC_CTRL0_FORCELINKDOWN; 2581 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, reg); 2582 } 2583 } else 2584 mvpp2_port_change(sc); 2585 } 2586 2587 void 2588 mvpp2_xlg_config(struct mvpp2_port *sc) 2589 { 2590 uint32_t ctl0, ctl4; 2591 2592 ctl0 = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG); 2593 ctl4 = mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL4_REG); 2594 2595 ctl0 |= MV_XLG_MAC_CTRL0_MACRESETN; 2596 ctl4 &= ~MV_XLG_MAC_CTRL4_EN_IDLE_CHECK_FOR_LINK; 2597 ctl4 |= MV_XLG_MAC_CTRL4_FORWARD_PFC_EN; 2598 ctl4 |= MV_XLG_MAC_CTRL4_FORWARD_802_3X_FC_EN; 2599 2600 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL0_REG, ctl0); 2601 mvpp2_xlg_write(sc, MV_XLG_PORT_MAC_CTRL4_REG, ctl4); 2602 2603 /* Port reset */ 2604 while ((mvpp2_xlg_read(sc, MV_XLG_PORT_MAC_CTRL0_REG) & 2605 MV_XLG_MAC_CTRL0_MACRESETN) == 0) 2606 ; 2607 } 2608 2609 void 2610 mvpp2_gmac_config(struct mvpp2_port *sc) 2611 { 2612 uint32_t ctl0, ctl2, ctl4, panc; 2613 2614 /* Setup phy. */ 2615 ctl0 = mvpp2_gmac_read(sc, MVPP2_PORT_CTRL0_REG); 2616 ctl2 = mvpp2_gmac_read(sc, MVPP2_PORT_CTRL2_REG); 2617 ctl4 = mvpp2_gmac_read(sc, MVPP2_PORT_CTRL4_REG); 2618 panc = mvpp2_gmac_read(sc, MVPP2_GMAC_AUTONEG_CONFIG); 2619 2620 ctl0 &= ~MVPP2_GMAC_PORT_TYPE_MASK; 2621 ctl2 &= ~(MVPP2_GMAC_PORT_RESET_MASK | MVPP2_GMAC_PCS_ENABLE_MASK | 2622 MVPP2_GMAC_INBAND_AN_MASK); 2623 panc &= ~(MVPP2_GMAC_AN_DUPLEX_EN | MVPP2_GMAC_FLOW_CTRL_AUTONEG | 2624 MVPP2_GMAC_FC_ADV_ASM_EN | MVPP2_GMAC_FC_ADV_EN | 2625 MVPP2_GMAC_AN_SPEED_EN | MVPP2_GMAC_IN_BAND_AUTONEG_BYPASS | 2626 MVPP2_GMAC_IN_BAND_AUTONEG); 2627 2628 switch (sc->sc_phy_mode) { 2629 case PHY_MODE_XAUI: 2630 case PHY_MODE_10GBASER: 2631 break; 2632 case PHY_MODE_2500BASEX: 2633 case PHY_MODE_1000BASEX: 2634 ctl2 |= MVPP2_GMAC_PCS_ENABLE_MASK; 2635 ctl4 &= ~MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL; 2636 ctl4 |= MVPP2_PORT_CTRL4_SYNC_BYPASS; 2637 ctl4 |= MVPP2_PORT_CTRL4_DP_CLK_SEL; 2638 ctl4 |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE; 2639 break; 2640 case PHY_MODE_SGMII: 2641 ctl2 |= MVPP2_GMAC_PCS_ENABLE_MASK; 2642 ctl2 |= MVPP2_GMAC_INBAND_AN_MASK; 2643 ctl4 &= ~MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL; 2644 ctl4 |= MVPP2_PORT_CTRL4_SYNC_BYPASS; 2645 ctl4 |= MVPP2_PORT_CTRL4_DP_CLK_SEL; 2646 ctl4 |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE; 2647 break; 2648 case PHY_MODE_RGMII: 2649 case PHY_MODE_RGMII_ID: 2650 case PHY_MODE_RGMII_RXID: 2651 case PHY_MODE_RGMII_TXID: 2652 ctl4 &= ~MVPP2_PORT_CTRL4_DP_CLK_SEL; 2653 ctl4 |= MVPP2_PORT_CTRL4_EXT_PIN_GMII_SEL; 2654 ctl4 |= MVPP2_PORT_CTRL4_SYNC_BYPASS; 2655 ctl4 |= MVPP2_PORT_CTRL4_QSGMII_BYPASS_ACTIVE; 2656 break; 2657 } 2658 2659 /* Use Auto-Negotiation for Inband Status only */ 2660 if (sc->sc_inband_status) { 2661 panc &= ~MVPP2_GMAC_CONFIG_MII_SPEED; 2662 panc &= ~MVPP2_GMAC_CONFIG_GMII_SPEED; 2663 panc &= ~MVPP2_GMAC_CONFIG_FULL_DUPLEX; 2664 panc |= MVPP2_GMAC_IN_BAND_AUTONEG; 2665 /* TODO: read mode from SFP */ 2666 if (sc->sc_phy_mode == PHY_MODE_SGMII) { 2667 /* SGMII */ 2668 panc |= MVPP2_GMAC_AN_SPEED_EN; 2669 panc |= MVPP2_GMAC_AN_DUPLEX_EN; 2670 } else { 2671 /* 802.3z */ 2672 ctl0 |= MVPP2_GMAC_PORT_TYPE_MASK; 2673 panc |= MVPP2_GMAC_CONFIG_GMII_SPEED; 2674 panc |= MVPP2_GMAC_CONFIG_FULL_DUPLEX; 2675 } 2676 } 2677 2678 mvpp2_gmac_write(sc, MVPP2_PORT_CTRL0_REG, ctl0); 2679 mvpp2_gmac_write(sc, MVPP2_PORT_CTRL2_REG, ctl2); 2680 mvpp2_gmac_write(sc, MVPP2_PORT_CTRL4_REG, ctl4); 2681 mvpp2_gmac_write(sc, MVPP2_GMAC_AUTONEG_CONFIG, panc); 2682 } 2683 2684 #define COMPHY_BASE 0x120000 2685 #define COMPHY_SIP_POWER_ON 0x82000001 2686 #define COMPHY_SIP_POWER_OFF 0x82000002 2687 #define COMPHY_SPEED(x) ((x) << 2) 2688 #define COMPHY_SPEED_1_25G 0 /* SGMII 1G */ 2689 #define COMPHY_SPEED_2_5G 1 2690 #define COMPHY_SPEED_3_125G 2 /* SGMII 2.5G */ 2691 #define COMPHY_SPEED_5G 3 2692 #define COMPHY_SPEED_5_15625G 4 /* XFI 5G */ 2693 #define COMPHY_SPEED_6G 5 2694 #define COMPHY_SPEED_10_3125G 6 /* XFI 10G */ 2695 #define COMPHY_UNIT(x) ((x) << 8) 2696 #define COMPHY_MODE(x) ((x) << 12) 2697 #define COMPHY_MODE_SATA 1 2698 #define COMPHY_MODE_SGMII 2 /* SGMII 1G */ 2699 #define COMPHY_MODE_HS_SGMII 3 /* SGMII 2.5G */ 2700 #define COMPHY_MODE_USB3H 4 2701 #define COMPHY_MODE_USB3D 5 2702 #define COMPHY_MODE_PCIE 6 2703 #define COMPHY_MODE_RXAUI 7 2704 #define COMPHY_MODE_XFI 8 2705 #define COMPHY_MODE_SFI 9 2706 #define COMPHY_MODE_USB3 10 2707 #define COMPHY_MODE_AP 11 2708 2709 void 2710 mvpp2_comphy_config(struct mvpp2_port *sc, int on) 2711 { 2712 int node, phys[2], lane, unit; 2713 uint32_t mode; 2714 2715 if (OF_getpropintarray(sc->sc_node, "phys", phys, sizeof(phys)) != 2716 sizeof(phys)) 2717 return; 2718 node = OF_getnodebyphandle(phys[0]); 2719 if (!node) 2720 return; 2721 2722 lane = OF_getpropint(node, "reg", 0); 2723 unit = phys[1]; 2724 2725 switch (sc->sc_phy_mode) { 2726 case PHY_MODE_XAUI: 2727 mode = COMPHY_MODE(COMPHY_MODE_RXAUI) | 2728 COMPHY_UNIT(unit); 2729 break; 2730 case PHY_MODE_10GBASER: 2731 mode = COMPHY_MODE(COMPHY_MODE_XFI) | 2732 COMPHY_SPEED(COMPHY_SPEED_10_3125G) | 2733 COMPHY_UNIT(unit); 2734 break; 2735 case PHY_MODE_2500BASEX: 2736 mode = COMPHY_MODE(COMPHY_MODE_HS_SGMII) | 2737 COMPHY_SPEED(COMPHY_SPEED_3_125G) | 2738 COMPHY_UNIT(unit); 2739 break; 2740 case PHY_MODE_1000BASEX: 2741 case PHY_MODE_SGMII: 2742 mode = COMPHY_MODE(COMPHY_MODE_SGMII) | 2743 COMPHY_SPEED(COMPHY_SPEED_1_25G) | 2744 COMPHY_UNIT(unit); 2745 break; 2746 default: 2747 return; 2748 } 2749 2750 if (on) 2751 smc_call(COMPHY_SIP_POWER_ON, sc->sc->sc_ioh_paddr + COMPHY_BASE, 2752 lane, mode); 2753 else 2754 smc_call(COMPHY_SIP_POWER_OFF, sc->sc->sc_ioh_paddr + COMPHY_BASE, 2755 lane, 0); 2756 } 2757 2758 void 2759 mvpp2_gop_config(struct mvpp2_port *sc) 2760 { 2761 uint32_t reg; 2762 2763 if (sc->sc->sc_rm == NULL) 2764 return; 2765 2766 if (sc->sc_phy_mode == PHY_MODE_RGMII || 2767 sc->sc_phy_mode == PHY_MODE_RGMII_ID || 2768 sc->sc_phy_mode == PHY_MODE_RGMII_RXID || 2769 sc->sc_phy_mode == PHY_MODE_RGMII_TXID) { 2770 if (sc->sc_gop_id == 0) 2771 return; 2772 reg = regmap_read_4(sc->sc->sc_rm, GENCONF_PORT_CTRL0); 2773 reg |= GENCONF_PORT_CTRL0_BUS_WIDTH_SELECT; 2774 regmap_write_4(sc->sc->sc_rm, GENCONF_PORT_CTRL0, reg); 2775 reg = regmap_read_4(sc->sc->sc_rm, GENCONF_CTRL0); 2776 if (sc->sc_gop_id == 2) 2777 reg |= GENCONF_CTRL0_PORT0_RGMII | 2778 GENCONF_CTRL0_PORT1_RGMII; 2779 else if (sc->sc_gop_id == 3) 2780 reg |= GENCONF_CTRL0_PORT1_RGMII_MII; 2781 regmap_write_4(sc->sc->sc_rm, GENCONF_CTRL0, reg); 2782 } else if (sc->sc_phy_mode == PHY_MODE_2500BASEX || 2783 sc->sc_phy_mode == PHY_MODE_1000BASEX || 2784 sc->sc_phy_mode == PHY_MODE_SGMII) { 2785 reg = regmap_read_4(sc->sc->sc_rm, GENCONF_PORT_CTRL0); 2786 reg |= GENCONF_PORT_CTRL0_BUS_WIDTH_SELECT | 2787 GENCONF_PORT_CTRL0_RX_DATA_SAMPLE; 2788 regmap_write_4(sc->sc->sc_rm, GENCONF_PORT_CTRL0, reg); 2789 if (sc->sc_gop_id > 1) { 2790 reg = regmap_read_4(sc->sc->sc_rm, GENCONF_CTRL0); 2791 if (sc->sc_gop_id == 2) 2792 reg &= ~GENCONF_CTRL0_PORT0_RGMII; 2793 else if (sc->sc_gop_id == 3) 2794 reg &= ~GENCONF_CTRL0_PORT1_RGMII_MII; 2795 regmap_write_4(sc->sc->sc_rm, GENCONF_CTRL0, reg); 2796 } 2797 } else if (sc->sc_phy_mode == PHY_MODE_10GBASER) { 2798 if (sc->sc_gop_id != 0) 2799 return; 2800 reg = mvpp2_xpcs_read(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG); 2801 reg &= ~MVPP22_XPCS_PCSMODE_MASK; 2802 reg &= ~MVPP22_XPCS_LANEACTIVE_MASK; 2803 reg |= 2 << MVPP22_XPCS_LANEACTIVE_OFFS; 2804 mvpp2_xpcs_write(sc, MVPP22_XPCS_GLOBAL_CFG_0_REG, reg); 2805 reg = mvpp2_mpcs_read(sc, MVPP22_MPCS40G_COMMON_CONTROL); 2806 reg &= ~MVPP22_MPCS_FORWARD_ERROR_CORRECTION_MASK; 2807 mvpp2_mpcs_write(sc, MVPP22_MPCS40G_COMMON_CONTROL, reg); 2808 reg = mvpp2_mpcs_read(sc, MVPP22_MPCS_CLOCK_RESET); 2809 reg &= ~MVPP22_MPCS_CLK_DIVISION_RATIO_MASK; 2810 reg |= MVPP22_MPCS_CLK_DIVISION_RATIO_DEFAULT; 2811 mvpp2_mpcs_write(sc, MVPP22_MPCS_CLOCK_RESET, reg); 2812 } else 2813 return; 2814 2815 reg = regmap_read_4(sc->sc->sc_rm, GENCONF_PORT_CTRL1); 2816 reg |= GENCONF_PORT_CTRL1_RESET(sc->sc_gop_id) | 2817 GENCONF_PORT_CTRL1_EN(sc->sc_gop_id); 2818 regmap_write_4(sc->sc->sc_rm, GENCONF_PORT_CTRL1, reg); 2819 2820 reg = regmap_read_4(sc->sc->sc_rm, GENCONF_PORT_CTRL0); 2821 reg |= GENCONF_PORT_CTRL0_CLK_DIV_PHASE_CLR; 2822 regmap_write_4(sc->sc->sc_rm, GENCONF_PORT_CTRL0, reg); 2823 2824 reg = regmap_read_4(sc->sc->sc_rm, GENCONF_SOFT_RESET1); 2825 reg |= GENCONF_SOFT_RESET1_GOP; 2826 regmap_write_4(sc->sc->sc_rm, GENCONF_SOFT_RESET1, reg); 2827 } 2828 2829 void 2830 mvpp2_gop_intr_mask(struct mvpp2_port *sc) 2831 { 2832 uint32_t reg; 2833 2834 if (sc->sc_gop_id == 0) { 2835 reg = mvpp2_xlg_read(sc, MV_XLG_EXTERNAL_INTERRUPT_MASK_REG); 2836 reg &= ~MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_XLG; 2837 reg &= ~MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_GIG; 2838 mvpp2_xlg_write(sc, MV_XLG_EXTERNAL_INTERRUPT_MASK_REG, reg); 2839 } 2840 2841 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_INT_SUM_MASK_REG); 2842 reg &= ~MVPP2_GMAC_INT_SUM_CAUSE_LINK_CHANGE; 2843 mvpp2_gmac_write(sc, MVPP2_GMAC_INT_SUM_MASK_REG, reg); 2844 } 2845 2846 void 2847 mvpp2_gop_intr_unmask(struct mvpp2_port *sc) 2848 { 2849 uint32_t reg; 2850 2851 reg = mvpp2_gmac_read(sc, MVPP2_GMAC_INT_SUM_MASK_REG); 2852 reg |= MVPP2_GMAC_INT_SUM_CAUSE_LINK_CHANGE; 2853 mvpp2_gmac_write(sc, MVPP2_GMAC_INT_SUM_MASK_REG, reg); 2854 2855 if (sc->sc_gop_id == 0) { 2856 reg = mvpp2_xlg_read(sc, MV_XLG_EXTERNAL_INTERRUPT_MASK_REG); 2857 if (sc->sc_phy_mode == PHY_MODE_10GBASER || 2858 sc->sc_phy_mode == PHY_MODE_XAUI) 2859 reg |= MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_XLG; 2860 else 2861 reg |= MV_XLG_EXTERNAL_INTERRUPT_LINK_CHANGE_GIG; 2862 mvpp2_xlg_write(sc, MV_XLG_EXTERNAL_INTERRUPT_MASK_REG, reg); 2863 } 2864 } 2865 2866 void 2867 mvpp2_down(struct mvpp2_port *sc) 2868 { 2869 struct ifnet *ifp = &sc->sc_ac.ac_if; 2870 uint32_t reg; 2871 int i; 2872 2873 timeout_del(&sc->sc_tick); 2874 2875 ifp->if_flags &= ~IFF_RUNNING; 2876 ifq_clr_oactive(&ifp->if_snd); 2877 2878 mvpp2_egress_disable(sc); 2879 mvpp2_ingress_disable(sc); 2880 2881 mvpp2_mac_reset_assert(sc); 2882 mvpp2_pcs_reset_assert(sc); 2883 2884 /* XXX: single vector */ 2885 mvpp2_interrupts_disable(sc, (1 << 0)); 2886 mvpp2_write(sc->sc, MVPP2_ISR_RX_TX_MASK_REG(sc->sc_id), 0); 2887 2888 reg = mvpp2_read(sc->sc, MVPP2_TX_PORT_FLUSH_REG); 2889 reg |= MVPP2_TX_PORT_FLUSH_MASK(sc->sc_id); 2890 mvpp2_write(sc->sc, MVPP2_TX_PORT_FLUSH_REG, reg); 2891 2892 for (i = 0; i < sc->sc_ntxq; i++) 2893 mvpp2_txq_hw_deinit(sc, &sc->sc_txqs[i]); 2894 2895 reg &= ~MVPP2_TX_PORT_FLUSH_MASK(sc->sc_id); 2896 mvpp2_write(sc->sc, MVPP2_TX_PORT_FLUSH_REG, reg); 2897 2898 for (i = 0; i < sc->sc_nrxq; i++) 2899 mvpp2_rxq_hw_deinit(sc, &sc->sc_rxqs[i]); 2900 2901 if (sc->sc_sfp) { 2902 rw_enter(&mvpp2_sff_lock, RW_WRITE); 2903 sfp_disable(sc->sc_sfp); 2904 rw_exit(&mvpp2_sff_lock); 2905 } 2906 } 2907 2908 void 2909 mvpp2_txq_hw_deinit(struct mvpp2_port *sc, struct mvpp2_tx_queue *txq) 2910 { 2911 struct mvpp2_buf *txb; 2912 int i, pending; 2913 uint32_t reg; 2914 2915 mvpp2_write(sc->sc, MVPP2_TXQ_NUM_REG, txq->id); 2916 reg = mvpp2_read(sc->sc, MVPP2_TXQ_PREF_BUF_REG); 2917 reg |= MVPP2_TXQ_DRAIN_EN_MASK; 2918 mvpp2_write(sc->sc, MVPP2_TXQ_PREF_BUF_REG, reg); 2919 2920 /* 2921 * the queue has been stopped so wait for all packets 2922 * to be transmitted. 2923 */ 2924 i = 0; 2925 do { 2926 if (i >= MVPP2_TX_PENDING_TIMEOUT_MSEC) { 2927 printf("%s: port %d: cleaning queue %d timed out\n", 2928 sc->sc_dev.dv_xname, sc->sc_id, txq->log_id); 2929 break; 2930 } 2931 delay(1000); 2932 i++; 2933 2934 pending = mvpp2_read(sc->sc, MVPP2_TXQ_PENDING_REG) & 2935 MVPP2_TXQ_PENDING_MASK; 2936 } while (pending); 2937 2938 reg &= ~MVPP2_TXQ_DRAIN_EN_MASK; 2939 mvpp2_write(sc->sc, MVPP2_TXQ_PREF_BUF_REG, reg); 2940 2941 mvpp2_write(sc->sc, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(txq->log_id), 0); 2942 mvpp2_write(sc->sc, MVPP2_TXQ_NUM_REG, txq->id); 2943 mvpp2_write(sc->sc, MVPP2_TXQ_DESC_ADDR_REG, 0); 2944 mvpp2_write(sc->sc, MVPP2_TXQ_DESC_SIZE_REG, 0); 2945 mvpp2_read(sc->sc, MVPP2_TXQ_SENT_REG(txq->id)); 2946 2947 for (i = 0; i < MVPP2_NTXDESC; i++) { 2948 txb = &txq->buf[i]; 2949 if (txb->mb_m) { 2950 bus_dmamap_sync(sc->sc_dmat, txb->mb_map, 0, 2951 txb->mb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 2952 bus_dmamap_unload(sc->sc_dmat, txb->mb_map); 2953 m_freem(txb->mb_m); 2954 } 2955 bus_dmamap_destroy(sc->sc_dmat, txb->mb_map); 2956 } 2957 2958 mvpp2_dmamem_free(sc->sc, txq->ring); 2959 free(txq->buf, M_DEVBUF, sizeof(struct mvpp2_buf) * 2960 MVPP2_NTXDESC); 2961 } 2962 2963 void 2964 mvpp2_rxq_hw_drop(struct mvpp2_port *sc, struct mvpp2_rx_queue *rxq) 2965 { 2966 struct mvpp2_rx_desc *rxd; 2967 struct mvpp2_bm_pool *bm; 2968 uint64_t phys, virt; 2969 uint32_t i, nrecv, pool; 2970 struct mvpp2_buf *rxb; 2971 2972 nrecv = mvpp2_rxq_received(sc, rxq->id); 2973 if (!nrecv) 2974 return; 2975 2976 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(rxq->ring), 0, 2977 MVPP2_DMA_LEN(rxq->ring), 2978 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 2979 2980 for (i = 0; i < nrecv; i++) { 2981 rxd = &rxq->descs[rxq->cons]; 2982 virt = rxd->buf_cookie_bm_qset_cls_info; 2983 pool = (virt >> 16) & 0xffff; 2984 KASSERT(pool < sc->sc->sc_npools); 2985 bm = &sc->sc->sc_bm_pools[pool]; 2986 KASSERT((virt & 0xffff) < MVPP2_BM_SIZE); 2987 rxb = &bm->rxbuf[virt & 0xffff]; 2988 KASSERT(rxb->mb_m != NULL); 2989 virt &= 0xffffffff; 2990 phys = rxb->mb_map->dm_segs[0].ds_addr; 2991 mvpp2_write(sc->sc, MVPP22_BM_ADDR_HIGH_RLS_REG, 2992 (((virt >> 32) & MVPP22_ADDR_HIGH_MASK) 2993 << MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT) | 2994 ((phys >> 32) & MVPP22_ADDR_HIGH_MASK)); 2995 mvpp2_write(sc->sc, MVPP2_BM_VIRT_RLS_REG, 2996 virt & 0xffffffff); 2997 mvpp2_write(sc->sc, MVPP2_BM_PHY_RLS_REG(pool), 2998 phys & 0xffffffff); 2999 rxq->cons = (rxq->cons + 1) % MVPP2_NRXDESC; 3000 } 3001 3002 bus_dmamap_sync(sc->sc_dmat, MVPP2_DMA_MAP(rxq->ring), 0, 3003 MVPP2_DMA_LEN(rxq->ring), 3004 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 3005 3006 mvpp2_rxq_status_update(sc, rxq->id, nrecv, nrecv); 3007 } 3008 3009 void 3010 mvpp2_rxq_hw_deinit(struct mvpp2_port *sc, struct mvpp2_rx_queue *rxq) 3011 { 3012 mvpp2_rxq_hw_drop(sc, rxq); 3013 3014 mvpp2_write(sc->sc, MVPP2_RXQ_STATUS_REG(rxq->id), 0); 3015 mvpp2_write(sc->sc, MVPP2_RXQ_NUM_REG, rxq->id); 3016 mvpp2_write(sc->sc, MVPP2_RXQ_DESC_ADDR_REG, 0); 3017 mvpp2_write(sc->sc, MVPP2_RXQ_DESC_SIZE_REG, 0); 3018 3019 mvpp2_dmamem_free(sc->sc, rxq->ring); 3020 } 3021 3022 void 3023 mvpp2_rxq_long_pool_set(struct mvpp2_port *port, int lrxq, int pool) 3024 { 3025 uint32_t val; 3026 int prxq; 3027 3028 /* get queue physical ID */ 3029 prxq = port->sc_rxqs[lrxq].id; 3030 3031 val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(prxq)); 3032 val &= ~MVPP2_RXQ_POOL_LONG_MASK; 3033 val |= ((pool << MVPP2_RXQ_POOL_LONG_OFFS) & MVPP2_RXQ_POOL_LONG_MASK); 3034 3035 mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(prxq), val); 3036 } 3037 3038 void 3039 mvpp2_rxq_short_pool_set(struct mvpp2_port *port, int lrxq, int pool) 3040 { 3041 uint32_t val; 3042 int prxq; 3043 3044 /* get queue physical ID */ 3045 prxq = port->sc_rxqs[lrxq].id; 3046 3047 val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(prxq)); 3048 val &= ~MVPP2_RXQ_POOL_SHORT_MASK; 3049 val |= ((pool << MVPP2_RXQ_POOL_SHORT_OFFS) & MVPP2_RXQ_POOL_SHORT_MASK); 3050 3051 mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(prxq), val); 3052 } 3053 3054 void 3055 mvpp2_iff(struct mvpp2_port *sc) 3056 { 3057 struct arpcom *ac = &sc->sc_ac; 3058 struct ifnet *ifp = &sc->sc_ac.ac_if; 3059 struct ether_multi *enm; 3060 struct ether_multistep step; 3061 3062 ifp->if_flags &= ~IFF_ALLMULTI; 3063 3064 /* Removes all but broadcast and (new) lladdr */ 3065 mvpp2_prs_mac_del_all(sc); 3066 3067 if (ifp->if_flags & IFF_PROMISC) { 3068 mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, 3069 MVPP2_PRS_L2_UNI_CAST, 1); 3070 mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, 3071 MVPP2_PRS_L2_MULTI_CAST, 1); 3072 return; 3073 } 3074 3075 mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, 3076 MVPP2_PRS_L2_UNI_CAST, 0); 3077 mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, 3078 MVPP2_PRS_L2_MULTI_CAST, 0); 3079 3080 if (ac->ac_multirangecnt > 0 || 3081 ac->ac_multicnt > MVPP2_PRS_MAC_MC_FILT_MAX) { 3082 ifp->if_flags |= IFF_ALLMULTI; 3083 mvpp2_prs_mac_promisc_set(sc->sc, sc->sc_id, 3084 MVPP2_PRS_L2_MULTI_CAST, 1); 3085 } else { 3086 ETHER_FIRST_MULTI(step, ac, enm); 3087 while (enm != NULL) { 3088 mvpp2_prs_mac_da_accept(sc, enm->enm_addrlo, 1); 3089 ETHER_NEXT_MULTI(step, enm); 3090 } 3091 } 3092 } 3093 3094 struct mvpp2_dmamem * 3095 mvpp2_dmamem_alloc(struct mvpp2_softc *sc, bus_size_t size, bus_size_t align) 3096 { 3097 struct mvpp2_dmamem *mdm; 3098 int nsegs; 3099 3100 mdm = malloc(sizeof(*mdm), M_DEVBUF, M_WAITOK | M_ZERO); 3101 mdm->mdm_size = size; 3102 3103 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 3104 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0) 3105 goto mdmfree; 3106 3107 if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &mdm->mdm_seg, 1, 3108 &nsegs, BUS_DMA_WAITOK) != 0) 3109 goto destroy; 3110 3111 if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size, 3112 &mdm->mdm_kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT) != 0) 3113 goto free; 3114 3115 if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size, 3116 NULL, BUS_DMA_WAITOK) != 0) 3117 goto unmap; 3118 3119 bzero(mdm->mdm_kva, size); 3120 3121 return (mdm); 3122 3123 unmap: 3124 bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size); 3125 free: 3126 bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1); 3127 destroy: 3128 bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map); 3129 mdmfree: 3130 free(mdm, M_DEVBUF, 0); 3131 3132 return (NULL); 3133 } 3134 3135 void 3136 mvpp2_dmamem_free(struct mvpp2_softc *sc, struct mvpp2_dmamem *mdm) 3137 { 3138 bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size); 3139 bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1); 3140 bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map); 3141 free(mdm, M_DEVBUF, 0); 3142 } 3143 3144 struct mbuf * 3145 mvpp2_alloc_mbuf(struct mvpp2_softc *sc, bus_dmamap_t map) 3146 { 3147 struct mbuf *m = NULL; 3148 3149 m = MCLGETL(NULL, M_DONTWAIT, MCLBYTES); 3150 if (!m) 3151 return (NULL); 3152 m->m_len = m->m_pkthdr.len = MCLBYTES; 3153 3154 if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT) != 0) { 3155 printf("%s: could not load mbuf DMA map", DEVNAME(sc)); 3156 m_freem(m); 3157 return (NULL); 3158 } 3159 3160 bus_dmamap_sync(sc->sc_dmat, map, 0, 3161 m->m_pkthdr.len, BUS_DMASYNC_PREREAD); 3162 3163 return (m); 3164 } 3165 3166 void 3167 mvpp2_interrupts_enable(struct mvpp2_port *port, int cpu_mask) 3168 { 3169 mvpp2_write(port->sc, MVPP2_ISR_ENABLE_REG(port->sc_id), 3170 MVPP2_ISR_ENABLE_INTERRUPT(cpu_mask)); 3171 } 3172 3173 void 3174 mvpp2_interrupts_disable(struct mvpp2_port *port, int cpu_mask) 3175 { 3176 mvpp2_write(port->sc, MVPP2_ISR_ENABLE_REG(port->sc_id), 3177 MVPP2_ISR_DISABLE_INTERRUPT(cpu_mask)); 3178 } 3179 3180 int 3181 mvpp2_egress_port(struct mvpp2_port *port) 3182 { 3183 return MVPP2_MAX_TCONT + port->sc_id; 3184 } 3185 3186 int 3187 mvpp2_txq_phys(int port, int txq) 3188 { 3189 return (MVPP2_MAX_TCONT + port) * MVPP2_MAX_TXQ + txq; 3190 } 3191 3192 void 3193 mvpp2_defaults_set(struct mvpp2_port *port) 3194 { 3195 int val, queue; 3196 3197 mvpp2_write(port->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG, 3198 mvpp2_egress_port(port)); 3199 mvpp2_write(port->sc, MVPP2_TXP_SCHED_CMD_1_REG, 0); 3200 3201 for (queue = 0; queue < MVPP2_MAX_TXQ; queue++) 3202 mvpp2_write(port->sc, MVPP2_TXQ_SCHED_TOKEN_CNTR_REG(queue), 0); 3203 3204 mvpp2_write(port->sc, MVPP2_TXP_SCHED_PERIOD_REG, port->sc->sc_tclk / 3205 (1000 * 1000)); 3206 val = mvpp2_read(port->sc, MVPP2_TXP_SCHED_REFILL_REG); 3207 val &= ~MVPP2_TXP_REFILL_PERIOD_ALL_MASK; 3208 val |= MVPP2_TXP_REFILL_PERIOD_MASK(1); 3209 val |= MVPP2_TXP_REFILL_TOKENS_ALL_MASK; 3210 mvpp2_write(port->sc, MVPP2_TXP_SCHED_REFILL_REG, val); 3211 val = MVPP2_TXP_TOKEN_SIZE_MAX; 3212 mvpp2_write(port->sc, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, val); 3213 3214 /* set maximum_low_latency_packet_size value to 256 */ 3215 mvpp2_write(port->sc, MVPP2_RX_CTRL_REG(port->sc_id), 3216 MVPP2_RX_USE_PSEUDO_FOR_CSUM_MASK | 3217 MVPP2_RX_LOW_LATENCY_PKT_SIZE(256)); 3218 3219 /* mask all interrupts to all present cpus */ 3220 mvpp2_interrupts_disable(port, (0xf << 0)); 3221 } 3222 3223 void 3224 mvpp2_ingress_enable(struct mvpp2_port *port) 3225 { 3226 uint32_t val; 3227 int lrxq, queue; 3228 3229 for (lrxq = 0; lrxq < port->sc_nrxq; lrxq++) { 3230 queue = port->sc_rxqs[lrxq].id; 3231 val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(queue)); 3232 val &= ~MVPP2_RXQ_DISABLE_MASK; 3233 mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(queue), val); 3234 } 3235 } 3236 3237 void 3238 mvpp2_ingress_disable(struct mvpp2_port *port) 3239 { 3240 uint32_t val; 3241 int lrxq, queue; 3242 3243 for (lrxq = 0; lrxq < port->sc_nrxq; lrxq++) { 3244 queue = port->sc_rxqs[lrxq].id; 3245 val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(queue)); 3246 val |= MVPP2_RXQ_DISABLE_MASK; 3247 mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(queue), val); 3248 } 3249 } 3250 3251 void 3252 mvpp2_egress_enable(struct mvpp2_port *port) 3253 { 3254 struct mvpp2_tx_queue *txq; 3255 uint32_t qmap; 3256 int queue; 3257 3258 qmap = 0; 3259 for (queue = 0; queue < port->sc_ntxq; queue++) { 3260 txq = &port->sc_txqs[queue]; 3261 3262 if (txq->descs != NULL) { 3263 qmap |= (1 << queue); 3264 } 3265 } 3266 3267 mvpp2_write(port->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG, 3268 mvpp2_egress_port(port)); 3269 mvpp2_write(port->sc, MVPP2_TXP_SCHED_Q_CMD_REG, qmap); 3270 } 3271 3272 void 3273 mvpp2_egress_disable(struct mvpp2_port *port) 3274 { 3275 uint32_t reg_data; 3276 int i; 3277 3278 mvpp2_write(port->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG, 3279 mvpp2_egress_port(port)); 3280 reg_data = (mvpp2_read(port->sc, MVPP2_TXP_SCHED_Q_CMD_REG)) & 3281 MVPP2_TXP_SCHED_ENQ_MASK; 3282 if (reg_data) 3283 mvpp2_write(port->sc, MVPP2_TXP_SCHED_Q_CMD_REG, 3284 reg_data << MVPP2_TXP_SCHED_DISQ_OFFSET); 3285 3286 i = 0; 3287 do { 3288 if (i >= MVPP2_TX_DISABLE_TIMEOUT_MSEC) { 3289 printf("%s: tx stop timed out, status=0x%08x\n", 3290 port->sc_dev.dv_xname, reg_data); 3291 break; 3292 } 3293 delay(1000); 3294 i++; 3295 reg_data = mvpp2_read(port->sc, MVPP2_TXP_SCHED_Q_CMD_REG); 3296 } while (reg_data & MVPP2_TXP_SCHED_ENQ_MASK); 3297 } 3298 3299 void 3300 mvpp2_port_enable(struct mvpp2_port *port) 3301 { 3302 uint32_t val; 3303 3304 if (port->sc_gop_id == 0 && (port->sc_phy_mode == PHY_MODE_10GBASER || 3305 port->sc_phy_mode == PHY_MODE_XAUI)) { 3306 val = mvpp2_xlg_read(port, MV_XLG_PORT_MAC_CTRL0_REG); 3307 val |= MV_XLG_MAC_CTRL0_PORTEN; 3308 val &= ~MV_XLG_MAC_CTRL0_MIBCNTDIS; 3309 mvpp2_xlg_write(port, MV_XLG_PORT_MAC_CTRL0_REG, val); 3310 } else { 3311 val = mvpp2_gmac_read(port, MVPP2_GMAC_CTRL_0_REG); 3312 val |= MVPP2_GMAC_PORT_EN_MASK; 3313 val |= MVPP2_GMAC_MIB_CNTR_EN_MASK; 3314 mvpp2_gmac_write(port, MVPP2_GMAC_CTRL_0_REG, val); 3315 } 3316 } 3317 3318 void 3319 mvpp2_port_disable(struct mvpp2_port *port) 3320 { 3321 uint32_t val; 3322 3323 if (port->sc_gop_id == 0 && (port->sc_phy_mode == PHY_MODE_10GBASER || 3324 port->sc_phy_mode == PHY_MODE_XAUI)) { 3325 val = mvpp2_xlg_read(port, MV_XLG_PORT_MAC_CTRL0_REG); 3326 val &= ~MV_XLG_MAC_CTRL0_PORTEN; 3327 mvpp2_xlg_write(port, MV_XLG_PORT_MAC_CTRL0_REG, val); 3328 } 3329 3330 val = mvpp2_gmac_read(port, MVPP2_GMAC_CTRL_0_REG); 3331 val &= ~MVPP2_GMAC_PORT_EN_MASK; 3332 mvpp2_gmac_write(port, MVPP2_GMAC_CTRL_0_REG, val); 3333 } 3334 3335 int 3336 mvpp2_rxq_received(struct mvpp2_port *port, int rxq_id) 3337 { 3338 uint32_t val = mvpp2_read(port->sc, MVPP2_RXQ_STATUS_REG(rxq_id)); 3339 3340 return val & MVPP2_RXQ_OCCUPIED_MASK; 3341 } 3342 3343 void 3344 mvpp2_rxq_status_update(struct mvpp2_port *port, int rxq_id, 3345 int used_count, int free_count) 3346 { 3347 uint32_t val = used_count | (free_count << MVPP2_RXQ_NUM_NEW_OFFSET); 3348 mvpp2_write(port->sc, MVPP2_RXQ_STATUS_UPDATE_REG(rxq_id), val); 3349 } 3350 3351 void 3352 mvpp2_rxq_offset_set(struct mvpp2_port *port, int prxq, int offset) 3353 { 3354 uint32_t val; 3355 3356 offset = offset >> 5; 3357 val = mvpp2_read(port->sc, MVPP2_RXQ_CONFIG_REG(prxq)); 3358 val &= ~MVPP2_RXQ_PACKET_OFFSET_MASK; 3359 val |= ((offset << MVPP2_RXQ_PACKET_OFFSET_OFFS) & 3360 MVPP2_RXQ_PACKET_OFFSET_MASK); 3361 mvpp2_write(port->sc, MVPP2_RXQ_CONFIG_REG(prxq), val); 3362 } 3363 3364 void 3365 mvpp2_txp_max_tx_size_set(struct mvpp2_port *port) 3366 { 3367 uint32_t val, size, mtu; 3368 int txq; 3369 3370 mtu = MCLBYTES * 8; 3371 if (mtu > MVPP2_TXP_MTU_MAX) 3372 mtu = MVPP2_TXP_MTU_MAX; 3373 3374 /* WA for wrong token bucket update: set MTU value = 3*real MTU value */ 3375 mtu = 3 * mtu; 3376 3377 /* indirect access to reg_valisters */ 3378 mvpp2_write(port->sc, MVPP2_TXP_SCHED_PORT_INDEX_REG, 3379 mvpp2_egress_port(port)); 3380 3381 /* set MTU */ 3382 val = mvpp2_read(port->sc, MVPP2_TXP_SCHED_MTU_REG); 3383 val &= ~MVPP2_TXP_MTU_MAX; 3384 val |= mtu; 3385 mvpp2_write(port->sc, MVPP2_TXP_SCHED_MTU_REG, val); 3386 3387 /* TXP token size and all TXqs token size must be larger that MTU */ 3388 val = mvpp2_read(port->sc, MVPP2_TXP_SCHED_TOKEN_SIZE_REG); 3389 size = val & MVPP2_TXP_TOKEN_SIZE_MAX; 3390 if (size < mtu) { 3391 size = mtu; 3392 val &= ~MVPP2_TXP_TOKEN_SIZE_MAX; 3393 val |= size; 3394 mvpp2_write(port->sc, MVPP2_TXP_SCHED_TOKEN_SIZE_REG, val); 3395 } 3396 3397 for (txq = 0; txq < port->sc_ntxq; txq++) { 3398 val = mvpp2_read(port->sc, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq)); 3399 size = val & MVPP2_TXQ_TOKEN_SIZE_MAX; 3400 3401 if (size < mtu) { 3402 size = mtu; 3403 val &= ~MVPP2_TXQ_TOKEN_SIZE_MAX; 3404 val |= size; 3405 mvpp2_write(port->sc, MVPP2_TXQ_SCHED_TOKEN_SIZE_REG(txq), val); 3406 } 3407 } 3408 } 3409 3410 void 3411 mvpp2_rx_pkts_coal_set(struct mvpp2_port *port, struct mvpp2_rx_queue *rxq, 3412 uint32_t pkts) 3413 { 3414 rxq->pkts_coal = 3415 pkts <= MVPP2_OCCUPIED_THRESH_MASK ? 3416 pkts : MVPP2_OCCUPIED_THRESH_MASK; 3417 3418 mvpp2_write(port->sc, MVPP2_RXQ_NUM_REG, rxq->id); 3419 mvpp2_write(port->sc, MVPP2_RXQ_THRESH_REG, rxq->pkts_coal); 3420 3421 } 3422 3423 void 3424 mvpp2_tx_pkts_coal_set(struct mvpp2_port *port, struct mvpp2_tx_queue *txq, 3425 uint32_t pkts) 3426 { 3427 txq->done_pkts_coal = 3428 pkts <= MVPP2_TRANSMITTED_THRESH_MASK ? 3429 pkts : MVPP2_TRANSMITTED_THRESH_MASK; 3430 3431 mvpp2_write(port->sc, MVPP2_TXQ_NUM_REG, txq->id); 3432 mvpp2_write(port->sc, MVPP2_TXQ_THRESH_REG, 3433 txq->done_pkts_coal << MVPP2_TRANSMITTED_THRESH_OFFSET); 3434 } 3435 3436 void 3437 mvpp2_rx_time_coal_set(struct mvpp2_port *port, struct mvpp2_rx_queue *rxq, 3438 uint32_t usec) 3439 { 3440 uint32_t val; 3441 3442 val = (port->sc->sc_tclk / (1000 * 1000)) * usec; 3443 mvpp2_write(port->sc, MVPP2_ISR_RX_THRESHOLD_REG(rxq->id), val); 3444 3445 rxq->time_coal = usec; 3446 } 3447 3448 void 3449 mvpp2_tx_time_coal_set(struct mvpp2_port *port, uint32_t usec) 3450 { 3451 uint32_t val; 3452 3453 val = (port->sc->sc_tclk / (1000 * 1000)) * usec; 3454 mvpp2_write(port->sc, MVPP2_ISR_TX_THRESHOLD_REG(port->sc_id), val); 3455 3456 port->sc_tx_time_coal = usec; 3457 } 3458 3459 void 3460 mvpp2_prs_shadow_ri_set(struct mvpp2_softc *sc, int index, 3461 uint32_t ri, uint32_t ri_mask) 3462 { 3463 sc->sc_prs_shadow[index].ri_mask = ri_mask; 3464 sc->sc_prs_shadow[index].ri = ri; 3465 } 3466 3467 void 3468 mvpp2_prs_tcam_lu_set(struct mvpp2_prs_entry *pe, uint32_t lu) 3469 { 3470 int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_LU_BYTE); 3471 3472 pe->tcam.byte[MVPP2_PRS_TCAM_LU_BYTE] = lu; 3473 pe->tcam.byte[enable_off] = MVPP2_PRS_LU_MASK; 3474 } 3475 3476 void 3477 mvpp2_prs_tcam_port_set(struct mvpp2_prs_entry *pe, uint32_t port, int add) 3478 { 3479 int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE); 3480 3481 if (add) 3482 pe->tcam.byte[enable_off] &= ~(1 << port); 3483 else 3484 pe->tcam.byte[enable_off] |= (1 << port); 3485 } 3486 3487 void 3488 mvpp2_prs_tcam_port_map_set(struct mvpp2_prs_entry *pe, uint32_t port_mask) 3489 { 3490 int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE); 3491 uint8_t mask = MVPP2_PRS_PORT_MASK; 3492 3493 pe->tcam.byte[MVPP2_PRS_TCAM_PORT_BYTE] = 0; 3494 pe->tcam.byte[enable_off] &= ~mask; 3495 pe->tcam.byte[enable_off] |= ~port_mask & MVPP2_PRS_PORT_MASK; 3496 } 3497 3498 uint32_t 3499 mvpp2_prs_tcam_port_map_get(struct mvpp2_prs_entry *pe) 3500 { 3501 int enable_off = MVPP2_PRS_TCAM_EN_OFFS(MVPP2_PRS_TCAM_PORT_BYTE); 3502 3503 return ~(pe->tcam.byte[enable_off]) & MVPP2_PRS_PORT_MASK; 3504 } 3505 3506 void 3507 mvpp2_prs_tcam_data_byte_set(struct mvpp2_prs_entry *pe, uint32_t offs, 3508 uint8_t byte, uint8_t enable) 3509 { 3510 pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(offs)] = byte; 3511 pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(offs)] = enable; 3512 } 3513 3514 void 3515 mvpp2_prs_tcam_data_byte_get(struct mvpp2_prs_entry *pe, uint32_t offs, 3516 uint8_t *byte, uint8_t *enable) 3517 { 3518 *byte = pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE(offs)]; 3519 *enable = pe->tcam.byte[MVPP2_PRS_TCAM_DATA_BYTE_EN(offs)]; 3520 } 3521 3522 int 3523 mvpp2_prs_tcam_data_cmp(struct mvpp2_prs_entry *pe, int offset, uint16_t data) 3524 { 3525 int byte_offset = MVPP2_PRS_TCAM_DATA_BYTE(offset); 3526 uint16_t tcam_data; 3527 3528 tcam_data = (pe->tcam.byte[byte_offset + 1] << 8) | 3529 pe->tcam.byte[byte_offset]; 3530 return tcam_data == data; 3531 } 3532 3533 void 3534 mvpp2_prs_tcam_ai_update(struct mvpp2_prs_entry *pe, uint32_t bits, uint32_t enable) 3535 { 3536 int i, ai_idx = MVPP2_PRS_TCAM_AI_BYTE; 3537 3538 for (i = 0; i < MVPP2_PRS_AI_BITS; i++) { 3539 if (!(enable & BIT(i))) 3540 continue; 3541 3542 if (bits & BIT(i)) 3543 pe->tcam.byte[ai_idx] |= BIT(i); 3544 else 3545 pe->tcam.byte[ai_idx] &= ~BIT(i); 3546 } 3547 3548 pe->tcam.byte[MVPP2_PRS_TCAM_EN_OFFS(ai_idx)] |= enable; 3549 } 3550 3551 int 3552 mvpp2_prs_tcam_ai_get(struct mvpp2_prs_entry *pe) 3553 { 3554 return pe->tcam.byte[MVPP2_PRS_TCAM_AI_BYTE]; 3555 } 3556 3557 void 3558 mvpp2_prs_tcam_data_word_get(struct mvpp2_prs_entry *pe, uint32_t data_offset, 3559 uint32_t *word, uint32_t *enable) 3560 { 3561 int index, position; 3562 uint8_t byte, mask; 3563 3564 for (index = 0; index < 4; index++) { 3565 position = (data_offset * sizeof(int)) + index; 3566 mvpp2_prs_tcam_data_byte_get(pe, position, &byte, &mask); 3567 ((uint8_t *)word)[index] = byte; 3568 ((uint8_t *)enable)[index] = mask; 3569 } 3570 } 3571 3572 void 3573 mvpp2_prs_match_etype(struct mvpp2_prs_entry *pe, uint32_t offs, 3574 uint16_t ether_type) 3575 { 3576 mvpp2_prs_tcam_data_byte_set(pe, offs + 0, ether_type >> 8, 0xff); 3577 mvpp2_prs_tcam_data_byte_set(pe, offs + 1, ether_type & 0xff, 0xff); 3578 } 3579 3580 void 3581 mvpp2_prs_sram_bits_set(struct mvpp2_prs_entry *pe, uint32_t bit, uint32_t val) 3582 { 3583 pe->sram.byte[bit / 8] |= (val << (bit % 8)); 3584 } 3585 3586 void 3587 mvpp2_prs_sram_bits_clear(struct mvpp2_prs_entry *pe, uint32_t bit, uint32_t val) 3588 { 3589 pe->sram.byte[bit / 8] &= ~(val << (bit % 8)); 3590 } 3591 3592 void 3593 mvpp2_prs_sram_ri_update(struct mvpp2_prs_entry *pe, uint32_t bits, uint32_t mask) 3594 { 3595 int i; 3596 3597 for (i = 0; i < MVPP2_PRS_SRAM_RI_CTRL_BITS; i++) { 3598 if (!(mask & BIT(i))) 3599 continue; 3600 3601 if (bits & BIT(i)) 3602 mvpp2_prs_sram_bits_set(pe, 3603 MVPP2_PRS_SRAM_RI_OFFS + i, 1); 3604 else 3605 mvpp2_prs_sram_bits_clear(pe, 3606 MVPP2_PRS_SRAM_RI_OFFS + i, 1); 3607 3608 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_RI_CTRL_OFFS + i, 1); 3609 } 3610 } 3611 3612 int 3613 mvpp2_prs_sram_ri_get(struct mvpp2_prs_entry *pe) 3614 { 3615 return pe->sram.word[MVPP2_PRS_SRAM_RI_WORD]; 3616 } 3617 3618 void 3619 mvpp2_prs_sram_ai_update(struct mvpp2_prs_entry *pe, uint32_t bits, uint32_t mask) 3620 { 3621 int i; 3622 3623 for (i = 0; i < MVPP2_PRS_SRAM_AI_CTRL_BITS; i++) { 3624 if (!(mask & BIT(i))) 3625 continue; 3626 3627 if (bits & BIT(i)) 3628 mvpp2_prs_sram_bits_set(pe, 3629 MVPP2_PRS_SRAM_AI_OFFS + i, 1); 3630 else 3631 mvpp2_prs_sram_bits_clear(pe, 3632 MVPP2_PRS_SRAM_AI_OFFS + i, 1); 3633 3634 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_AI_CTRL_OFFS + i, 1); 3635 } 3636 } 3637 3638 int 3639 mvpp2_prs_sram_ai_get(struct mvpp2_prs_entry *pe) 3640 { 3641 uint8_t bits; 3642 int ai_off = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_AI_OFFS); 3643 int ai_en_off = ai_off + 1; 3644 int ai_shift = MVPP2_PRS_SRAM_AI_OFFS % 8; 3645 3646 bits = (pe->sram.byte[ai_off] >> ai_shift) | 3647 (pe->sram.byte[ai_en_off] << (8 - ai_shift)); 3648 3649 return bits; 3650 } 3651 3652 void 3653 mvpp2_prs_sram_shift_set(struct mvpp2_prs_entry *pe, int shift, uint32_t op) 3654 { 3655 if (shift < 0) { 3656 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1); 3657 shift = -shift; 3658 } else { 3659 mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_SHIFT_SIGN_BIT, 1); 3660 } 3661 3662 pe->sram.byte[MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_SHIFT_OFFS)] |= 3663 shift & MVPP2_PRS_SRAM_SHIFT_MASK; 3664 mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS, 3665 MVPP2_PRS_SRAM_OP_SEL_SHIFT_MASK); 3666 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_OP_SEL_SHIFT_OFFS, op); 3667 mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1); 3668 } 3669 3670 void 3671 mvpp2_prs_sram_offset_set(struct mvpp2_prs_entry *pe, uint32_t type, int offset, 3672 uint32_t op) 3673 { 3674 uint8_t udf_byte, udf_byte_offset; 3675 uint8_t op_sel_udf_byte, op_sel_udf_byte_offset; 3676 3677 udf_byte = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_UDF_OFFS + 3678 MVPP2_PRS_SRAM_UDF_BITS); 3679 udf_byte_offset = (8 - (MVPP2_PRS_SRAM_UDF_OFFS % 8)); 3680 op_sel_udf_byte = MVPP2_BIT_TO_BYTE(MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS + 3681 MVPP2_PRS_SRAM_OP_SEL_UDF_BITS); 3682 op_sel_udf_byte_offset = (8 - (MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS % 8)); 3683 3684 if (offset < 0) { 3685 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1); 3686 offset = -offset; 3687 } else { 3688 mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_SIGN_BIT, 1); 3689 } 3690 3691 mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_OFFS, 3692 MVPP2_PRS_SRAM_UDF_MASK); 3693 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_OFFS, offset); 3694 pe->sram.byte[udf_byte] &= ~(MVPP2_PRS_SRAM_UDF_MASK >> udf_byte_offset); 3695 pe->sram.byte[udf_byte] |= (offset >> udf_byte_offset); 3696 mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS, 3697 MVPP2_PRS_SRAM_UDF_TYPE_MASK); 3698 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_UDF_TYPE_OFFS, type); 3699 mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS, 3700 MVPP2_PRS_SRAM_OP_SEL_UDF_MASK); 3701 mvpp2_prs_sram_bits_set(pe, MVPP2_PRS_SRAM_OP_SEL_UDF_OFFS, op); 3702 pe->sram.byte[op_sel_udf_byte] &= ~(MVPP2_PRS_SRAM_OP_SEL_UDF_MASK >> 3703 op_sel_udf_byte_offset); 3704 pe->sram.byte[op_sel_udf_byte] |= (op >> op_sel_udf_byte_offset); 3705 mvpp2_prs_sram_bits_clear(pe, MVPP2_PRS_SRAM_OP_SEL_BASE_OFFS, 1); 3706 } 3707 3708 void 3709 mvpp2_prs_sram_next_lu_set(struct mvpp2_prs_entry *pe, uint32_t lu) 3710 { 3711 int sram_next_off = MVPP2_PRS_SRAM_NEXT_LU_OFFS; 3712 3713 mvpp2_prs_sram_bits_clear(pe, sram_next_off, MVPP2_PRS_SRAM_NEXT_LU_MASK); 3714 mvpp2_prs_sram_bits_set(pe, sram_next_off, lu); 3715 } 3716 3717 void 3718 mvpp2_prs_shadow_set(struct mvpp2_softc *sc, int index, uint32_t lu) 3719 { 3720 sc->sc_prs_shadow[index].valid = 1; 3721 sc->sc_prs_shadow[index].lu = lu; 3722 } 3723 3724 int 3725 mvpp2_prs_hw_write(struct mvpp2_softc *sc, struct mvpp2_prs_entry *pe) 3726 { 3727 int i; 3728 3729 if (pe->index > MVPP2_PRS_TCAM_SRAM_SIZE - 1) 3730 return EINVAL; 3731 3732 pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] &= ~MVPP2_PRS_TCAM_INV_MASK; 3733 mvpp2_write(sc, MVPP2_PRS_TCAM_IDX_REG, pe->index); 3734 for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) 3735 mvpp2_write(sc, MVPP2_PRS_TCAM_DATA_REG(i), pe->tcam.word[i]); 3736 mvpp2_write(sc, MVPP2_PRS_SRAM_IDX_REG, pe->index); 3737 for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++) 3738 mvpp2_write(sc, MVPP2_PRS_SRAM_DATA_REG(i), pe->sram.word[i]); 3739 3740 return 0; 3741 } 3742 3743 int 3744 mvpp2_prs_hw_read(struct mvpp2_softc *sc, struct mvpp2_prs_entry *pe, int tid) 3745 { 3746 int i; 3747 3748 if (tid > MVPP2_PRS_TCAM_SRAM_SIZE - 1) 3749 return EINVAL; 3750 3751 memset(pe, 0, sizeof(*pe)); 3752 pe->index = tid; 3753 3754 mvpp2_write(sc, MVPP2_PRS_TCAM_IDX_REG, pe->index); 3755 pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] = 3756 mvpp2_read(sc, MVPP2_PRS_TCAM_DATA_REG(MVPP2_PRS_TCAM_INV_WORD)); 3757 if (pe->tcam.word[MVPP2_PRS_TCAM_INV_WORD] & MVPP2_PRS_TCAM_INV_MASK) 3758 return EINVAL; 3759 for (i = 0; i < MVPP2_PRS_TCAM_WORDS; i++) 3760 pe->tcam.word[i] = 3761 mvpp2_read(sc, MVPP2_PRS_TCAM_DATA_REG(i)); 3762 3763 mvpp2_write(sc, MVPP2_PRS_SRAM_IDX_REG, pe->index); 3764 for (i = 0; i < MVPP2_PRS_SRAM_WORDS; i++) 3765 pe->sram.word[i] = 3766 mvpp2_read(sc, MVPP2_PRS_SRAM_DATA_REG(i)); 3767 3768 return 0; 3769 } 3770 3771 int 3772 mvpp2_prs_flow_find(struct mvpp2_softc *sc, int flow) 3773 { 3774 struct mvpp2_prs_entry pe; 3775 uint8_t bits; 3776 int tid; 3777 3778 for (tid = MVPP2_PRS_TCAM_SRAM_SIZE - 1; tid >= 0; tid--) { 3779 if (!sc->sc_prs_shadow[tid].valid || 3780 sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_FLOWS) 3781 continue; 3782 3783 mvpp2_prs_hw_read(sc, &pe, tid); 3784 bits = mvpp2_prs_sram_ai_get(&pe); 3785 3786 if ((bits & MVPP2_PRS_FLOW_ID_MASK) == flow) 3787 return tid; 3788 } 3789 3790 return -1; 3791 } 3792 3793 int 3794 mvpp2_prs_tcam_first_free(struct mvpp2_softc *sc, uint8_t start, uint8_t end) 3795 { 3796 uint8_t tmp; 3797 int tid; 3798 3799 if (start > end) { 3800 tmp = end; 3801 end = start; 3802 start = tmp; 3803 } 3804 3805 for (tid = start; tid <= end; tid++) { 3806 if (!sc->sc_prs_shadow[tid].valid) 3807 return tid; 3808 } 3809 3810 return -1; 3811 } 3812 3813 void 3814 mvpp2_prs_mac_drop_all_set(struct mvpp2_softc *sc, uint32_t port, int add) 3815 { 3816 struct mvpp2_prs_entry pe; 3817 3818 if (sc->sc_prs_shadow[MVPP2_PE_DROP_ALL].valid) { 3819 mvpp2_prs_hw_read(sc, &pe, MVPP2_PE_DROP_ALL); 3820 } else { 3821 memset(&pe, 0, sizeof(pe)); 3822 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); 3823 pe.index = MVPP2_PE_DROP_ALL; 3824 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DROP_MASK, 3825 MVPP2_PRS_RI_DROP_MASK); 3826 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 3827 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 3828 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC); 3829 mvpp2_prs_tcam_port_map_set(&pe, 0); 3830 } 3831 3832 mvpp2_prs_tcam_port_set(&pe, port, add); 3833 mvpp2_prs_hw_write(sc, &pe); 3834 } 3835 3836 void 3837 mvpp2_prs_mac_promisc_set(struct mvpp2_softc *sc, uint32_t port, int l2_cast, 3838 int add) 3839 { 3840 struct mvpp2_prs_entry pe; 3841 uint8_t cast_match; 3842 uint32_t ri; 3843 int tid; 3844 3845 if (l2_cast == MVPP2_PRS_L2_UNI_CAST) { 3846 cast_match = MVPP2_PRS_UCAST_VAL; 3847 tid = MVPP2_PE_MAC_UC_PROMISCUOUS; 3848 ri = MVPP2_PRS_RI_L2_UCAST; 3849 } else { 3850 cast_match = MVPP2_PRS_MCAST_VAL; 3851 tid = MVPP2_PE_MAC_MC_PROMISCUOUS; 3852 ri = MVPP2_PRS_RI_L2_MCAST; 3853 } 3854 3855 if (sc->sc_prs_shadow[tid].valid) { 3856 mvpp2_prs_hw_read(sc, &pe, tid); 3857 } else { 3858 memset(&pe, 0, sizeof(pe)); 3859 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); 3860 pe.index = tid; 3861 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA); 3862 mvpp2_prs_sram_ri_update(&pe, ri, MVPP2_PRS_RI_L2_CAST_MASK); 3863 mvpp2_prs_tcam_data_byte_set(&pe, 0, cast_match, 3864 MVPP2_PRS_CAST_MASK); 3865 mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN, 3866 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 3867 mvpp2_prs_tcam_port_map_set(&pe, 0); 3868 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC); 3869 } 3870 3871 mvpp2_prs_tcam_port_set(&pe, port, add); 3872 mvpp2_prs_hw_write(sc, &pe); 3873 } 3874 3875 void 3876 mvpp2_prs_dsa_tag_set(struct mvpp2_softc *sc, uint32_t port, int add, 3877 int tagged, int extend) 3878 { 3879 struct mvpp2_prs_entry pe; 3880 int32_t tid, shift; 3881 3882 if (extend) { 3883 tid = tagged ? MVPP2_PE_EDSA_TAGGED : MVPP2_PE_EDSA_UNTAGGED; 3884 shift = 8; 3885 } else { 3886 tid = tagged ? MVPP2_PE_DSA_TAGGED : MVPP2_PE_DSA_UNTAGGED; 3887 shift = 4; 3888 } 3889 3890 if (sc->sc_prs_shadow[tid].valid) { 3891 mvpp2_prs_hw_read(sc, &pe, tid); 3892 } else { 3893 memset(&pe, 0, sizeof(pe)); 3894 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA); 3895 pe.index = tid; 3896 mvpp2_prs_sram_shift_set(&pe, shift, 3897 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 3898 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_DSA); 3899 if (tagged) { 3900 mvpp2_prs_tcam_data_byte_set(&pe, 0, 3901 MVPP2_PRS_TCAM_DSA_TAGGED_BIT, 3902 MVPP2_PRS_TCAM_DSA_TAGGED_BIT); 3903 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK); 3904 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN); 3905 } else { 3906 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE, 3907 MVPP2_PRS_RI_VLAN_MASK); 3908 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2); 3909 } 3910 mvpp2_prs_tcam_port_map_set(&pe, 0); 3911 } 3912 3913 mvpp2_prs_tcam_port_set(&pe, port, add); 3914 mvpp2_prs_hw_write(sc, &pe); 3915 } 3916 3917 void 3918 mvpp2_prs_dsa_tag_ethertype_set(struct mvpp2_softc *sc, uint32_t port, 3919 int add, int tagged, int extend) 3920 { 3921 struct mvpp2_prs_entry pe; 3922 int32_t tid, shift, port_mask; 3923 3924 if (extend) { 3925 tid = tagged ? MVPP2_PE_EDSA_TAGGED : MVPP2_PE_EDSA_UNTAGGED; 3926 port_mask = 0; 3927 shift = 8; 3928 } else { 3929 tid = tagged ? MVPP2_PE_DSA_TAGGED : MVPP2_PE_DSA_UNTAGGED; 3930 port_mask = MVPP2_PRS_PORT_MASK; 3931 shift = 4; 3932 } 3933 3934 if (sc->sc_prs_shadow[tid].valid) { 3935 mvpp2_prs_hw_read(sc, &pe, tid); 3936 } else { 3937 memset(&pe, 0, sizeof(pe)); 3938 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_DSA); 3939 pe.index = tid; 3940 mvpp2_prs_match_etype(&pe, 0, 0xdada); 3941 mvpp2_prs_match_etype(&pe, 2, 0); 3942 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_DSA_MASK, 3943 MVPP2_PRS_RI_DSA_MASK); 3944 mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN + shift, 3945 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 3946 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_DSA); 3947 if (tagged) { 3948 mvpp2_prs_tcam_data_byte_set(&pe, 3949 MVPP2_ETH_TYPE_LEN + 2 + 3, 3950 MVPP2_PRS_TCAM_DSA_TAGGED_BIT, 3951 MVPP2_PRS_TCAM_DSA_TAGGED_BIT); 3952 mvpp2_prs_sram_ai_update(&pe, 0, MVPP2_PRS_SRAM_AI_MASK); 3953 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_VLAN); 3954 } else { 3955 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_VLAN_NONE, 3956 MVPP2_PRS_RI_VLAN_MASK); 3957 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_L2); 3958 } 3959 mvpp2_prs_tcam_port_map_set(&pe, port_mask); 3960 } 3961 3962 mvpp2_prs_tcam_port_set(&pe, port, add); 3963 mvpp2_prs_hw_write(sc, &pe); 3964 } 3965 3966 struct mvpp2_prs_entry * 3967 mvpp2_prs_vlan_find(struct mvpp2_softc *sc, uint16_t tpid, int ai) 3968 { 3969 struct mvpp2_prs_entry *pe; 3970 uint32_t ri_bits, ai_bits; 3971 int match, tid; 3972 3973 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); 3974 if (pe == NULL) 3975 return NULL; 3976 3977 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN); 3978 3979 for (tid = MVPP2_PE_FIRST_FREE_TID; tid <= MVPP2_PE_LAST_FREE_TID; tid++) { 3980 if (!sc->sc_prs_shadow[tid].valid || 3981 sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN) 3982 continue; 3983 mvpp2_prs_hw_read(sc, pe, tid); 3984 match = mvpp2_prs_tcam_data_cmp(pe, 0, swap16(tpid)); 3985 if (!match) 3986 continue; 3987 ri_bits = mvpp2_prs_sram_ri_get(pe); 3988 ri_bits &= MVPP2_PRS_RI_VLAN_MASK; 3989 ai_bits = mvpp2_prs_tcam_ai_get(pe); 3990 ai_bits &= ~MVPP2_PRS_DBL_VLAN_AI_BIT; 3991 if (ai != ai_bits) 3992 continue; 3993 if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE || 3994 ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE) 3995 return pe; 3996 } 3997 3998 free(pe, M_TEMP, sizeof(*pe)); 3999 return NULL; 4000 } 4001 4002 int 4003 mvpp2_prs_vlan_add(struct mvpp2_softc *sc, uint16_t tpid, int ai, uint32_t port_map) 4004 { 4005 struct mvpp2_prs_entry *pe; 4006 uint32_t ri_bits; 4007 int tid_aux, tid; 4008 int ret = 0; 4009 4010 pe = mvpp2_prs_vlan_find(sc, tpid, ai); 4011 if (pe == NULL) { 4012 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_LAST_FREE_TID, 4013 MVPP2_PE_FIRST_FREE_TID); 4014 if (tid < 0) 4015 return tid; 4016 4017 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); 4018 if (pe == NULL) 4019 return ENOMEM; 4020 4021 /* get last double vlan tid */ 4022 for (tid_aux = MVPP2_PE_LAST_FREE_TID; 4023 tid_aux >= MVPP2_PE_FIRST_FREE_TID; tid_aux--) { 4024 if (!sc->sc_prs_shadow[tid_aux].valid || 4025 sc->sc_prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN) 4026 continue; 4027 mvpp2_prs_hw_read(sc, pe, tid_aux); 4028 ri_bits = mvpp2_prs_sram_ri_get(pe); 4029 if ((ri_bits & MVPP2_PRS_RI_VLAN_MASK) == 4030 MVPP2_PRS_RI_VLAN_DOUBLE) 4031 break; 4032 } 4033 4034 if (tid <= tid_aux) { 4035 ret = EINVAL; 4036 goto error; 4037 } 4038 4039 memset(pe, 0, sizeof(*pe)); 4040 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN); 4041 pe->index = tid; 4042 mvpp2_prs_match_etype(pe, 0, tpid); 4043 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_L2); 4044 mvpp2_prs_sram_shift_set(pe, MVPP2_VLAN_TAG_LEN, 4045 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 4046 mvpp2_prs_sram_ai_update(pe, 0, MVPP2_PRS_SRAM_AI_MASK); 4047 if (ai == MVPP2_PRS_SINGLE_VLAN_AI) { 4048 mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_SINGLE, 4049 MVPP2_PRS_RI_VLAN_MASK); 4050 } else { 4051 ai |= MVPP2_PRS_DBL_VLAN_AI_BIT; 4052 mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_TRIPLE, 4053 MVPP2_PRS_RI_VLAN_MASK); 4054 } 4055 mvpp2_prs_tcam_ai_update(pe, ai, MVPP2_PRS_SRAM_AI_MASK); 4056 mvpp2_prs_shadow_set(sc, pe->index, MVPP2_PRS_LU_VLAN); 4057 } 4058 4059 mvpp2_prs_tcam_port_map_set(pe, port_map); 4060 mvpp2_prs_hw_write(sc, pe); 4061 4062 error: 4063 free(pe, M_TEMP, sizeof(*pe)); 4064 return ret; 4065 } 4066 4067 int 4068 mvpp2_prs_double_vlan_ai_free_get(struct mvpp2_softc *sc) 4069 { 4070 int i; 4071 4072 for (i = 1; i < MVPP2_PRS_DBL_VLANS_MAX; i++) 4073 if (!sc->sc_prs_double_vlans[i]) 4074 return i; 4075 4076 return -1; 4077 } 4078 4079 struct mvpp2_prs_entry * 4080 mvpp2_prs_double_vlan_find(struct mvpp2_softc *sc, uint16_t tpid1, uint16_t tpid2) 4081 { 4082 struct mvpp2_prs_entry *pe; 4083 uint32_t ri_mask; 4084 int match, tid; 4085 4086 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); 4087 if (pe == NULL) 4088 return NULL; 4089 4090 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN); 4091 4092 for (tid = MVPP2_PE_FIRST_FREE_TID; tid <= MVPP2_PE_LAST_FREE_TID; tid++) { 4093 if (!sc->sc_prs_shadow[tid].valid || 4094 sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_VLAN) 4095 continue; 4096 4097 mvpp2_prs_hw_read(sc, pe, tid); 4098 match = mvpp2_prs_tcam_data_cmp(pe, 0, swap16(tpid1)) && 4099 mvpp2_prs_tcam_data_cmp(pe, 4, swap16(tpid2)); 4100 if (!match) 4101 continue; 4102 ri_mask = mvpp2_prs_sram_ri_get(pe) & MVPP2_PRS_RI_VLAN_MASK; 4103 if (ri_mask == MVPP2_PRS_RI_VLAN_DOUBLE) 4104 return pe; 4105 } 4106 4107 free(pe, M_TEMP, sizeof(*pe)); 4108 return NULL; 4109 } 4110 4111 int 4112 mvpp2_prs_double_vlan_add(struct mvpp2_softc *sc, uint16_t tpid1, uint16_t tpid2, 4113 uint32_t port_map) 4114 { 4115 struct mvpp2_prs_entry *pe; 4116 int tid_aux, tid, ai, ret = 0; 4117 uint32_t ri_bits; 4118 4119 pe = mvpp2_prs_double_vlan_find(sc, tpid1, tpid2); 4120 if (pe == NULL) { 4121 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 4122 MVPP2_PE_LAST_FREE_TID); 4123 if (tid < 0) 4124 return tid; 4125 4126 pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT); 4127 if (pe == NULL) 4128 return ENOMEM; 4129 4130 ai = mvpp2_prs_double_vlan_ai_free_get(sc); 4131 if (ai < 0) { 4132 ret = ai; 4133 goto error; 4134 } 4135 4136 for (tid_aux = MVPP2_PE_FIRST_FREE_TID; 4137 tid_aux <= MVPP2_PE_LAST_FREE_TID; tid_aux++) { 4138 if (!sc->sc_prs_shadow[tid_aux].valid || 4139 sc->sc_prs_shadow[tid_aux].lu != MVPP2_PRS_LU_VLAN) 4140 continue; 4141 mvpp2_prs_hw_read(sc, pe, tid_aux); 4142 ri_bits = mvpp2_prs_sram_ri_get(pe); 4143 ri_bits &= MVPP2_PRS_RI_VLAN_MASK; 4144 if (ri_bits == MVPP2_PRS_RI_VLAN_SINGLE || 4145 ri_bits == MVPP2_PRS_RI_VLAN_TRIPLE) 4146 break; 4147 } 4148 4149 if (tid >= tid_aux) { 4150 ret = ERANGE; 4151 goto error; 4152 } 4153 4154 memset(pe, 0, sizeof(*pe)); 4155 mvpp2_prs_tcam_lu_set(pe, MVPP2_PRS_LU_VLAN); 4156 pe->index = tid; 4157 sc->sc_prs_double_vlans[ai] = 1; 4158 mvpp2_prs_match_etype(pe, 0, tpid1); 4159 mvpp2_prs_match_etype(pe, 4, tpid2); 4160 mvpp2_prs_sram_next_lu_set(pe, MVPP2_PRS_LU_VLAN); 4161 mvpp2_prs_sram_shift_set(pe, 2 * MVPP2_VLAN_TAG_LEN, 4162 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 4163 mvpp2_prs_sram_ri_update(pe, MVPP2_PRS_RI_VLAN_DOUBLE, 4164 MVPP2_PRS_RI_VLAN_MASK); 4165 mvpp2_prs_sram_ai_update(pe, ai | MVPP2_PRS_DBL_VLAN_AI_BIT, 4166 MVPP2_PRS_SRAM_AI_MASK); 4167 mvpp2_prs_shadow_set(sc, pe->index, MVPP2_PRS_LU_VLAN); 4168 } 4169 4170 mvpp2_prs_tcam_port_map_set(pe, port_map); 4171 mvpp2_prs_hw_write(sc, pe); 4172 4173 error: 4174 free(pe, M_TEMP, sizeof(*pe)); 4175 return ret; 4176 } 4177 4178 int 4179 mvpp2_prs_ip4_proto(struct mvpp2_softc *sc, uint16_t proto, uint32_t ri, 4180 uint32_t ri_mask) 4181 { 4182 struct mvpp2_prs_entry pe; 4183 int tid; 4184 4185 if ((proto != IPPROTO_TCP) && (proto != IPPROTO_UDP) && 4186 (proto != IPPROTO_IGMP)) 4187 return EINVAL; 4188 4189 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 4190 MVPP2_PE_LAST_FREE_TID); 4191 if (tid < 0) 4192 return tid; 4193 4194 memset(&pe, 0, sizeof(pe)); 4195 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4); 4196 pe.index = tid; 4197 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP4); 4198 mvpp2_prs_sram_shift_set(&pe, 12, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 4199 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4, 4200 sizeof(struct ip) - 4, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 4201 mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT, 4202 MVPP2_PRS_IPV4_DIP_AI_BIT); 4203 mvpp2_prs_sram_ri_update(&pe, ri, ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK); 4204 mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, MVPP2_PRS_TCAM_PROTO_MASK_L); 4205 mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, MVPP2_PRS_TCAM_PROTO_MASK); 4206 mvpp2_prs_tcam_data_byte_set(&pe, 5, proto, MVPP2_PRS_TCAM_PROTO_MASK); 4207 mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV4_DIP_AI_BIT); 4208 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 4209 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4); 4210 mvpp2_prs_hw_write(sc, &pe); 4211 4212 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 4213 MVPP2_PE_LAST_FREE_TID); 4214 if (tid < 0) 4215 return tid; 4216 4217 pe.index = tid; 4218 pe.sram.word[MVPP2_PRS_SRAM_RI_WORD] = 0x0; 4219 pe.sram.word[MVPP2_PRS_SRAM_RI_CTRL_WORD] = 0x0; 4220 mvpp2_prs_sram_ri_update(&pe, ri, ri_mask); 4221 mvpp2_prs_sram_ri_update(&pe, ri | MVPP2_PRS_RI_IP_FRAG_MASK, 4222 ri_mask | MVPP2_PRS_RI_IP_FRAG_MASK); 4223 mvpp2_prs_tcam_data_byte_set(&pe, 2, 0x00, 0x0); 4224 mvpp2_prs_tcam_data_byte_set(&pe, 3, 0x00, 0x0); 4225 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4); 4226 mvpp2_prs_hw_write(sc, &pe); 4227 4228 return 0; 4229 } 4230 4231 int 4232 mvpp2_prs_ip4_cast(struct mvpp2_softc *sc, uint16_t l3_cast) 4233 { 4234 struct mvpp2_prs_entry pe; 4235 int mask, tid; 4236 4237 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 4238 MVPP2_PE_LAST_FREE_TID); 4239 if (tid < 0) 4240 return tid; 4241 4242 memset(&pe, 0, sizeof(pe)); 4243 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP4); 4244 pe.index = tid; 4245 4246 switch (l3_cast) { 4247 case MVPP2_PRS_L3_MULTI_CAST: 4248 mvpp2_prs_tcam_data_byte_set(&pe, 0, MVPP2_PRS_IPV4_MC, 4249 MVPP2_PRS_IPV4_MC_MASK); 4250 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_MCAST, 4251 MVPP2_PRS_RI_L3_ADDR_MASK); 4252 break; 4253 case MVPP2_PRS_L3_BROAD_CAST: 4254 mask = MVPP2_PRS_IPV4_BC_MASK; 4255 mvpp2_prs_tcam_data_byte_set(&pe, 0, mask, mask); 4256 mvpp2_prs_tcam_data_byte_set(&pe, 1, mask, mask); 4257 mvpp2_prs_tcam_data_byte_set(&pe, 2, mask, mask); 4258 mvpp2_prs_tcam_data_byte_set(&pe, 3, mask, mask); 4259 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_BCAST, 4260 MVPP2_PRS_RI_L3_ADDR_MASK); 4261 break; 4262 default: 4263 return EINVAL; 4264 } 4265 4266 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 4267 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 4268 mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV4_DIP_AI_BIT, 4269 MVPP2_PRS_IPV4_DIP_AI_BIT); 4270 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 4271 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP4); 4272 mvpp2_prs_hw_write(sc, &pe); 4273 4274 return 0; 4275 } 4276 4277 int 4278 mvpp2_prs_ip6_proto(struct mvpp2_softc *sc, uint16_t proto, uint32_t ri, 4279 uint32_t ri_mask) 4280 { 4281 struct mvpp2_prs_entry pe; 4282 int tid; 4283 4284 if ((proto != IPPROTO_TCP) && (proto != IPPROTO_UDP) && 4285 (proto != IPPROTO_ICMPV6) && (proto != IPPROTO_IPIP)) 4286 return EINVAL; 4287 4288 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 4289 MVPP2_PE_LAST_FREE_TID); 4290 if (tid < 0) 4291 return tid; 4292 4293 memset(&pe, 0, sizeof(pe)); 4294 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6); 4295 pe.index = tid; 4296 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 4297 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_GEN_BIT, 1); 4298 mvpp2_prs_sram_ri_update(&pe, ri, ri_mask); 4299 mvpp2_prs_sram_offset_set(&pe, MVPP2_PRS_SRAM_UDF_TYPE_L4, 4300 sizeof(struct ip6_hdr) - 6, MVPP2_PRS_SRAM_OP_SEL_UDF_ADD); 4301 mvpp2_prs_tcam_data_byte_set(&pe, 0, proto, MVPP2_PRS_TCAM_PROTO_MASK); 4302 mvpp2_prs_tcam_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, 4303 MVPP2_PRS_IPV6_NO_EXT_AI_BIT); 4304 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 4305 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP6); 4306 mvpp2_prs_hw_write(sc, &pe); 4307 4308 return 0; 4309 } 4310 4311 int 4312 mvpp2_prs_ip6_cast(struct mvpp2_softc *sc, uint16_t l3_cast) 4313 { 4314 struct mvpp2_prs_entry pe; 4315 int tid; 4316 4317 if (l3_cast != MVPP2_PRS_L3_MULTI_CAST) 4318 return EINVAL; 4319 4320 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_FIRST_FREE_TID, 4321 MVPP2_PE_LAST_FREE_TID); 4322 if (tid < 0) 4323 return tid; 4324 4325 memset(&pe, 0, sizeof(pe)); 4326 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_IP6); 4327 pe.index = tid; 4328 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_IP6); 4329 mvpp2_prs_sram_ri_update(&pe, MVPP2_PRS_RI_L3_MCAST, 4330 MVPP2_PRS_RI_L3_ADDR_MASK); 4331 mvpp2_prs_sram_ai_update(&pe, MVPP2_PRS_IPV6_NO_EXT_AI_BIT, 4332 MVPP2_PRS_IPV6_NO_EXT_AI_BIT); 4333 mvpp2_prs_sram_shift_set(&pe, -18, MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 4334 mvpp2_prs_tcam_data_byte_set(&pe, 0, MVPP2_PRS_IPV6_MC, 4335 MVPP2_PRS_IPV6_MC_MASK); 4336 mvpp2_prs_tcam_ai_update(&pe, 0, MVPP2_PRS_IPV6_NO_EXT_AI_BIT); 4337 mvpp2_prs_tcam_port_map_set(&pe, MVPP2_PRS_PORT_MASK); 4338 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_IP6); 4339 mvpp2_prs_hw_write(sc, &pe); 4340 4341 return 0; 4342 } 4343 4344 int 4345 mvpp2_prs_mac_range_equals(struct mvpp2_prs_entry *pe, const uint8_t *da, 4346 uint8_t *mask) 4347 { 4348 uint8_t tcam_byte, tcam_mask; 4349 int index; 4350 4351 for (index = 0; index < ETHER_ADDR_LEN; index++) { 4352 mvpp2_prs_tcam_data_byte_get(pe, index, &tcam_byte, 4353 &tcam_mask); 4354 if (tcam_mask != mask[index]) 4355 return 0; 4356 if ((tcam_mask & tcam_byte) != (da[index] & mask[index])) 4357 return 0; 4358 } 4359 4360 return 1; 4361 } 4362 4363 int 4364 mvpp2_prs_mac_da_range_find(struct mvpp2_softc *sc, int pmap, const uint8_t *da, 4365 uint8_t *mask, int udf_type) 4366 { 4367 struct mvpp2_prs_entry pe; 4368 int tid; 4369 4370 for (tid = MVPP2_PE_MAC_RANGE_START; tid <= MVPP2_PE_MAC_RANGE_END; 4371 tid++) { 4372 uint32_t entry_pmap; 4373 4374 if (!sc->sc_prs_shadow[tid].valid || 4375 (sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_MAC) || 4376 (sc->sc_prs_shadow[tid].udf != udf_type)) 4377 continue; 4378 4379 mvpp2_prs_hw_read(sc, &pe, tid); 4380 entry_pmap = mvpp2_prs_tcam_port_map_get(&pe); 4381 if (mvpp2_prs_mac_range_equals(&pe, da, mask) && 4382 entry_pmap == pmap) 4383 return tid; 4384 } 4385 4386 return -1; 4387 } 4388 4389 int 4390 mvpp2_prs_mac_da_accept(struct mvpp2_port *port, const uint8_t *da, int add) 4391 { 4392 struct mvpp2_softc *sc = port->sc; 4393 struct mvpp2_prs_entry pe; 4394 uint32_t pmap, len, ri; 4395 uint8_t mask[ETHER_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 4396 int tid; 4397 4398 memset(&pe, 0, sizeof(pe)); 4399 4400 tid = mvpp2_prs_mac_da_range_find(sc, BIT(port->sc_id), da, mask, 4401 MVPP2_PRS_UDF_MAC_DEF); 4402 if (tid < 0) { 4403 if (!add) 4404 return 0; 4405 4406 tid = mvpp2_prs_tcam_first_free(sc, MVPP2_PE_MAC_RANGE_START, 4407 MVPP2_PE_MAC_RANGE_END); 4408 if (tid < 0) 4409 return tid; 4410 4411 pe.index = tid; 4412 mvpp2_prs_tcam_port_map_set(&pe, 0); 4413 } else { 4414 mvpp2_prs_hw_read(sc, &pe, tid); 4415 } 4416 4417 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_MAC); 4418 4419 mvpp2_prs_tcam_port_set(&pe, port->sc_id, add); 4420 4421 /* invalidate the entry if no ports are left enabled */ 4422 pmap = mvpp2_prs_tcam_port_map_get(&pe); 4423 if (pmap == 0) { 4424 if (add) 4425 return -1; 4426 mvpp2_prs_hw_inv(sc, pe.index); 4427 sc->sc_prs_shadow[pe.index].valid = 0; 4428 return 0; 4429 } 4430 4431 mvpp2_prs_sram_next_lu_set(&pe, MVPP2_PRS_LU_DSA); 4432 4433 len = ETHER_ADDR_LEN; 4434 while (len--) 4435 mvpp2_prs_tcam_data_byte_set(&pe, len, da[len], 0xff); 4436 4437 if (ETHER_IS_BROADCAST(da)) 4438 ri = MVPP2_PRS_RI_L2_BCAST; 4439 else if (ETHER_IS_MULTICAST(da)) 4440 ri = MVPP2_PRS_RI_L2_MCAST; 4441 else 4442 ri = MVPP2_PRS_RI_L2_UCAST | MVPP2_PRS_RI_MAC_ME_MASK; 4443 4444 mvpp2_prs_sram_ri_update(&pe, ri, MVPP2_PRS_RI_L2_CAST_MASK | 4445 MVPP2_PRS_RI_MAC_ME_MASK); 4446 mvpp2_prs_shadow_ri_set(sc, pe.index, ri, MVPP2_PRS_RI_L2_CAST_MASK | 4447 MVPP2_PRS_RI_MAC_ME_MASK); 4448 mvpp2_prs_sram_shift_set(&pe, 2 * ETHER_ADDR_LEN, 4449 MVPP2_PRS_SRAM_OP_SEL_SHIFT_ADD); 4450 sc->sc_prs_shadow[pe.index].udf = MVPP2_PRS_UDF_MAC_DEF; 4451 mvpp2_prs_shadow_set(sc, pe.index, MVPP2_PRS_LU_MAC); 4452 mvpp2_prs_hw_write(sc, &pe); 4453 4454 return 0; 4455 } 4456 4457 void 4458 mvpp2_prs_mac_del_all(struct mvpp2_port *port) 4459 { 4460 struct mvpp2_softc *sc = port->sc; 4461 struct mvpp2_prs_entry pe; 4462 uint32_t pmap; 4463 int index, tid; 4464 4465 for (tid = MVPP2_PE_MAC_RANGE_START; tid <= MVPP2_PE_MAC_RANGE_END; 4466 tid++) { 4467 uint8_t da[ETHER_ADDR_LEN], da_mask[ETHER_ADDR_LEN]; 4468 4469 if (!sc->sc_prs_shadow[tid].valid || 4470 (sc->sc_prs_shadow[tid].lu != MVPP2_PRS_LU_MAC) || 4471 (sc->sc_prs_shadow[tid].udf != MVPP2_PRS_UDF_MAC_DEF)) 4472 continue; 4473 4474 mvpp2_prs_hw_read(sc, &pe, tid); 4475 pmap = mvpp2_prs_tcam_port_map_get(&pe); 4476 4477 if (!(pmap & (1 << port->sc_id))) 4478 continue; 4479 4480 for (index = 0; index < ETHER_ADDR_LEN; index++) 4481 mvpp2_prs_tcam_data_byte_get(&pe, index, &da[index], 4482 &da_mask[index]); 4483 4484 if (ETHER_IS_BROADCAST(da) || ETHER_IS_EQ(da, port->sc_lladdr)) 4485 continue; 4486 4487 mvpp2_prs_mac_da_accept(port, da, 0); 4488 } 4489 } 4490 4491 int 4492 mvpp2_prs_tag_mode_set(struct mvpp2_softc *sc, int port_id, int type) 4493 { 4494 switch (type) { 4495 case MVPP2_TAG_TYPE_EDSA: 4496 mvpp2_prs_dsa_tag_set(sc, port_id, 1, MVPP2_PRS_TAGGED, 4497 MVPP2_PRS_EDSA); 4498 mvpp2_prs_dsa_tag_set(sc, port_id, 1, MVPP2_PRS_UNTAGGED, 4499 MVPP2_PRS_EDSA); 4500 mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_TAGGED, 4501 MVPP2_PRS_DSA); 4502 mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_UNTAGGED, 4503 MVPP2_PRS_DSA); 4504 break; 4505 case MVPP2_TAG_TYPE_DSA: 4506 mvpp2_prs_dsa_tag_set(sc, port_id, 1, MVPP2_PRS_TAGGED, 4507 MVPP2_PRS_DSA); 4508 mvpp2_prs_dsa_tag_set(sc, port_id, 1, MVPP2_PRS_UNTAGGED, 4509 MVPP2_PRS_DSA); 4510 mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_TAGGED, 4511 MVPP2_PRS_EDSA); 4512 mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_UNTAGGED, 4513 MVPP2_PRS_EDSA); 4514 break; 4515 case MVPP2_TAG_TYPE_MH: 4516 case MVPP2_TAG_TYPE_NONE: 4517 mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_TAGGED, 4518 MVPP2_PRS_DSA); 4519 mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_UNTAGGED, 4520 MVPP2_PRS_DSA); 4521 mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_TAGGED, 4522 MVPP2_PRS_EDSA); 4523 mvpp2_prs_dsa_tag_set(sc, port_id, 0, MVPP2_PRS_UNTAGGED, 4524 MVPP2_PRS_EDSA); 4525 break; 4526 default: 4527 if ((type < 0) || (type > MVPP2_TAG_TYPE_EDSA)) 4528 return EINVAL; 4529 break; 4530 } 4531 4532 return 0; 4533 } 4534 4535 int 4536 mvpp2_prs_def_flow(struct mvpp2_port *port) 4537 { 4538 struct mvpp2_prs_entry pe; 4539 int tid; 4540 4541 memset(&pe, 0, sizeof(pe)); 4542 4543 tid = mvpp2_prs_flow_find(port->sc, port->sc_id); 4544 if (tid < 0) { 4545 tid = mvpp2_prs_tcam_first_free(port->sc, 4546 MVPP2_PE_LAST_FREE_TID, MVPP2_PE_FIRST_FREE_TID); 4547 if (tid < 0) 4548 return tid; 4549 4550 pe.index = tid; 4551 mvpp2_prs_sram_ai_update(&pe, port->sc_id, 4552 MVPP2_PRS_FLOW_ID_MASK); 4553 mvpp2_prs_sram_bits_set(&pe, MVPP2_PRS_SRAM_LU_DONE_BIT, 1); 4554 mvpp2_prs_shadow_set(port->sc, pe.index, MVPP2_PRS_LU_FLOWS); 4555 } else { 4556 mvpp2_prs_hw_read(port->sc, &pe, tid); 4557 } 4558 4559 mvpp2_prs_tcam_lu_set(&pe, MVPP2_PRS_LU_FLOWS); 4560 mvpp2_prs_tcam_port_map_set(&pe, (1 << port->sc_id)); 4561 mvpp2_prs_hw_write(port->sc, &pe); 4562 return 0; 4563 } 4564 4565 void 4566 mvpp2_cls_flow_write(struct mvpp2_softc *sc, struct mvpp2_cls_flow_entry *fe) 4567 { 4568 mvpp2_write(sc, MVPP2_CLS_FLOW_INDEX_REG, fe->index); 4569 mvpp2_write(sc, MVPP2_CLS_FLOW_TBL0_REG, fe->data[0]); 4570 mvpp2_write(sc, MVPP2_CLS_FLOW_TBL1_REG, fe->data[1]); 4571 mvpp2_write(sc, MVPP2_CLS_FLOW_TBL2_REG, fe->data[2]); 4572 } 4573 4574 void 4575 mvpp2_cls_lookup_write(struct mvpp2_softc *sc, struct mvpp2_cls_lookup_entry *le) 4576 { 4577 uint32_t val; 4578 4579 val = (le->way << MVPP2_CLS_LKP_INDEX_WAY_OFFS) | le->lkpid; 4580 mvpp2_write(sc, MVPP2_CLS_LKP_INDEX_REG, val); 4581 mvpp2_write(sc, MVPP2_CLS_LKP_TBL_REG, le->data); 4582 } 4583 4584 void 4585 mvpp2_cls_init(struct mvpp2_softc *sc) 4586 { 4587 struct mvpp2_cls_lookup_entry le; 4588 struct mvpp2_cls_flow_entry fe; 4589 int index; 4590 4591 mvpp2_write(sc, MVPP2_CLS_MODE_REG, MVPP2_CLS_MODE_ACTIVE_MASK); 4592 memset(&fe.data, 0, sizeof(fe.data)); 4593 for (index = 0; index < MVPP2_CLS_FLOWS_TBL_SIZE; index++) { 4594 fe.index = index; 4595 mvpp2_cls_flow_write(sc, &fe); 4596 } 4597 le.data = 0; 4598 for (index = 0; index < MVPP2_CLS_LKP_TBL_SIZE; index++) { 4599 le.lkpid = index; 4600 le.way = 0; 4601 mvpp2_cls_lookup_write(sc, &le); 4602 le.way = 1; 4603 mvpp2_cls_lookup_write(sc, &le); 4604 } 4605 } 4606 4607 void 4608 mvpp2_cls_port_config(struct mvpp2_port *port) 4609 { 4610 struct mvpp2_cls_lookup_entry le; 4611 uint32_t val; 4612 4613 /* set way for the port */ 4614 val = mvpp2_read(port->sc, MVPP2_CLS_PORT_WAY_REG); 4615 val &= ~MVPP2_CLS_PORT_WAY_MASK(port->sc_id); 4616 mvpp2_write(port->sc, MVPP2_CLS_PORT_WAY_REG, val); 4617 4618 /* 4619 * pick the entry to be accessed in lookup ID decoding table 4620 * according to the way and lkpid. 4621 */ 4622 le.lkpid = port->sc_id; 4623 le.way = 0; 4624 le.data = 0; 4625 4626 /* set initial CPU queue for receiving packets */ 4627 le.data &= ~MVPP2_CLS_LKP_TBL_RXQ_MASK; 4628 le.data |= (port->sc_id * 32); 4629 4630 /* disable classification engines */ 4631 le.data &= ~MVPP2_CLS_LKP_TBL_LOOKUP_EN_MASK; 4632 4633 /* update lookup ID table entry */ 4634 mvpp2_cls_lookup_write(port->sc, &le); 4635 } 4636 4637 void 4638 mvpp2_cls_oversize_rxq_set(struct mvpp2_port *port) 4639 { 4640 uint32_t val; 4641 4642 mvpp2_write(port->sc, MVPP2_CLS_OVERSIZE_RXQ_LOW_REG(port->sc_id), 4643 (port->sc_id * 32) & MVPP2_CLS_OVERSIZE_RXQ_LOW_MASK); 4644 mvpp2_write(port->sc, MVPP2_CLS_SWFWD_P2HQ_REG(port->sc_id), 4645 (port->sc_id * 32) >> MVPP2_CLS_OVERSIZE_RXQ_LOW_BITS); 4646 val = mvpp2_read(port->sc, MVPP2_CLS_SWFWD_PCTRL_REG); 4647 val &= ~MVPP2_CLS_SWFWD_PCTRL_MASK(port->sc_id); 4648 mvpp2_write(port->sc, MVPP2_CLS_SWFWD_PCTRL_REG, val); 4649 } 4650