1 /* $NetBSD: if_mvxpevar.h,v 1.4 2018/04/19 21:50:08 christos Exp $ */ 2 /* 3 * Copyright (c) 2015 Internet Initiative Japan Inc. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #ifndef _IF_MVXPEVAR_H_ 28 #define _IF_MVXPEVAR_H_ 29 #include <net/if.h> 30 #include <dev/marvell/mvxpbmvar.h> 31 32 /* 33 * Limit of packet sizes. 34 */ 35 #define MVXPE_HWHEADER_SIZE 2 /* Marvell Header */ 36 #define MVXPE_MRU 2000 /* Max Receive Unit */ 37 #define MVXPE_MTU MVXPE_MRU /* Max Transmit Unit */ 38 39 /* 40 * Default limit of queue length 41 * 42 * queue 0 is lowest priority and queue 7 is highest priority. 43 * 44 * XXX: packet classifier is not implement yet 45 */ 46 #define MVXPE_RX_QUEUE_LIMIT_0 IFQ_MAXLEN 47 #define MVXPE_RX_QUEUE_LIMIT_1 8 48 #define MVXPE_RX_QUEUE_LIMIT_2 8 49 #define MVXPE_RX_QUEUE_LIMIT_3 8 50 #define MVXPE_RX_QUEUE_LIMIT_4 8 51 #define MVXPE_RX_QUEUE_LIMIT_5 8 52 #define MVXPE_RX_QUEUE_LIMIT_6 8 53 #define MVXPE_RX_QUEUE_LIMIT_7 8 54 55 #define MVXPE_TX_QUEUE_LIMIT_0 IFQ_MAXLEN 56 #define MVXPE_TX_QUEUE_LIMIT_1 8 57 #define MVXPE_TX_QUEUE_LIMIT_2 8 58 #define MVXPE_TX_QUEUE_LIMIT_3 8 59 #define MVXPE_TX_QUEUE_LIMIT_4 8 60 #define MVXPE_TX_QUEUE_LIMIT_5 8 61 #define MVXPE_TX_QUEUE_LIMIT_6 8 62 #define MVXPE_TX_QUEUE_LIMIT_7 8 63 64 /* interrupt is triggered when corossing (queuelen / RATIO) */ 65 #define MVXPE_RXTH_RATIO 8 66 #define MVXPE_RXTH_REFILL_RATIO 2 67 #define MVXPE_TXTH_RATIO 8 68 69 /* 70 * Device Register access 71 */ 72 #define MVXPE_READ(sc, reg) \ 73 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)) 74 #define MVXPE_WRITE(sc, reg, val) \ 75 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 76 77 #define MVXPE_READ_REGION(sc, reg, val, c) \ 78 bus_space_read_region_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val), (c)) 79 #define MVXPE_WRITE_REGION(sc, reg, val, c) \ 80 bus_space_write_region_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val), (c)) 81 82 #define MVXPE_READ_MIB(sc, reg) \ 83 bus_space_read_4((sc)->sc_iot, (sc)->sc_mibh, (reg)) 84 85 #define MVXPE_IS_LINKUP(sc) \ 86 (MVXPE_READ((sc), MVXPE_PSR) & MVXPE_PSR_LINKUP) 87 88 #define MVXPE_IS_QUEUE_BUSY(queues, q) \ 89 ((((queues) >> (q)) & 0x1)) 90 91 /* 92 * EEE: Lower Power Idle config 93 * Default timer is duration of MTU sized frame transmission. 94 * The timer can be negotiated by LLDP protocol, but we have no 95 * support. 96 */ 97 #define MVXPE_LPI_TS (MVXPE_MRU * 8 / 1000) /* [us] */ 98 #define MVXPE_LPI_TW (MVXPE_MRU * 8 / 1000) /* [us] */ 99 #define MVXPE_LPI_LI (MVXPE_MRU * 8 / 1000) /* [us] */ 100 101 /* 102 * DMA Descriptor 103 * 104 * the ethernet device has 8 rx/tx DMA queues. each of queue has its own 105 * decriptor list. descriptors are simply index by counter inside the device. 106 */ 107 #define MVXPE_TX_RING_CNT IFQ_MAXLEN 108 #define MVXPE_TX_RING_MSK (MVXPE_TX_RING_CNT - 1) 109 #define MVXPE_TX_RING_NEXT(x) (((x) + 1) & MVXPE_TX_RING_MSK) 110 #define MVXPE_RX_RING_CNT IFQ_MAXLEN 111 #define MVXPE_RX_RING_MSK (MVXPE_RX_RING_CNT - 1) 112 #define MVXPE_RX_RING_NEXT(x) (((x) + 1) & MVXPE_RX_RING_MSK) 113 #define MVXPE_TX_SEGLIMIT 32 114 115 struct mvxpe_rx_ring { 116 /* Real descriptors array. shared by RxDMA */ 117 struct mvxpe_rx_desc *rx_descriptors; 118 bus_dmamap_t rx_descriptors_map; 119 120 /* Managment entries for each of descritors */ 121 struct mvxpe_rx_handle { 122 struct mvxpe_rx_desc *rxdesc_va; 123 off_t rxdesc_off; /* from rx_descriptors[0] */ 124 struct mvxpbm_chunk *chunk; 125 } rx_handle[MVXPE_RX_RING_CNT]; 126 127 /* locks */ 128 kmutex_t rx_ring_mtx; 129 130 /* Index */ 131 int rx_dma; 132 int rx_cpu; 133 134 /* Limit */ 135 int rx_queue_len; 136 int rx_queue_th_received; 137 int rx_queue_th_free; 138 int rx_queue_th_time; /* [Tclk] */ 139 }; 140 141 struct mvxpe_tx_ring { 142 /* Real descriptors array. shared by TxDMA */ 143 struct mvxpe_tx_desc *tx_descriptors; 144 bus_dmamap_t tx_descriptors_map; 145 146 /* Managment entries for each of descritors */ 147 struct mvxpe_tx_handle { 148 struct mvxpe_tx_desc *txdesc_va; 149 off_t txdesc_off; /* from tx_descriptors[0] */ 150 struct mbuf *txdesc_mbuf; 151 bus_dmamap_t txdesc_mbuf_map; 152 } tx_handle[MVXPE_TX_RING_CNT]; 153 154 /* locks */ 155 kmutex_t tx_ring_mtx; 156 157 /* Index */ 158 int tx_used; 159 int tx_dma; 160 int tx_cpu; 161 162 /* Limit */ 163 int tx_queue_len; 164 int tx_queue_th_free; 165 }; 166 167 static __inline int 168 tx_counter_adv(int ctr, int n) 169 { 170 /* XXX: lock or atomic */ 171 ctr += n; 172 while (ctr >= MVXPE_TX_RING_CNT) 173 ctr -= MVXPE_TX_RING_CNT; 174 175 return ctr; 176 } 177 178 static __inline int 179 rx_counter_adv(int ctr, int n) 180 { 181 /* XXX: lock or atomic */ 182 ctr += n; 183 while (ctr >= MVXPE_TX_RING_CNT) 184 ctr -= MVXPE_TX_RING_CNT; 185 186 return ctr; 187 } 188 189 /* 190 * Timeout control 191 */ 192 #define MVXPE_PHY_TIMEOUT 10000 /* msec */ 193 #define RX_DISABLE_TIMEOUT 0x1000000 /* times */ 194 #define TX_DISABLE_TIMEOUT 0x1000000 /* times */ 195 #define TX_FIFO_EMPTY_TIMEOUT 0x1000000 /* times */ 196 197 /* 198 * Event counter 199 */ 200 #ifdef MVXPE_EVENT_COUNTERS 201 #define MVXPE_EVCNT_INCR(ev) (ev)->ev_count++ 202 #define MVXPE_EVCNT_ADD(ev, val) (ev)->ev_count += (val) 203 #else 204 #define MVXPE_EVCNT_INCR(ev) /* nothing */ 205 #define MVXPE_EVCNT_ADD(ev, val) /* nothing */ 206 #endif 207 struct mvxpe_evcnt { 208 /* 209 * Master Interrupt Handler 210 */ 211 struct evcnt ev_i_rxtxth; 212 struct evcnt ev_i_rxtx; 213 struct evcnt ev_i_misc; 214 215 /* 216 * RXTXTH Interrupt 217 */ 218 struct evcnt ev_rxtxth_txerr; 219 220 /* 221 * MISC Interrupt 222 */ 223 struct evcnt ev_misc_phystatuschng; 224 struct evcnt ev_misc_linkchange; 225 struct evcnt ev_misc_iae; 226 struct evcnt ev_misc_rxoverrun; 227 struct evcnt ev_misc_rxcrc; 228 struct evcnt ev_misc_rxlargepacket; 229 struct evcnt ev_misc_txunderrun; 230 struct evcnt ev_misc_prbserr; 231 struct evcnt ev_misc_srse; 232 struct evcnt ev_misc_txreq; 233 234 /* 235 * RxTx Interrupt 236 */ 237 struct evcnt ev_rxtx_rreq; 238 struct evcnt ev_rxtx_rpq; 239 struct evcnt ev_rxtx_tbrq; 240 struct evcnt ev_rxtx_rxtxth; 241 struct evcnt ev_rxtx_txerr; 242 struct evcnt ev_rxtx_misc; 243 244 /* 245 * Link 246 */ 247 struct evcnt ev_link_up; 248 struct evcnt ev_link_down; 249 250 /* 251 * Rx Descriptor 252 */ 253 struct evcnt ev_rxd_ce; 254 struct evcnt ev_rxd_or; 255 struct evcnt ev_rxd_mf; 256 struct evcnt ev_rxd_re; 257 struct evcnt ev_rxd_scat; 258 259 /* 260 * Tx Descriptor 261 */ 262 struct evcnt ev_txd_lc; 263 struct evcnt ev_txd_ur; 264 struct evcnt ev_txd_rl; 265 struct evcnt ev_txd_oth; 266 267 /* 268 * Status Registers 269 */ 270 struct evcnt ev_reg_pdfc; /* Rx Port Discard Frame Counter */ 271 struct evcnt ev_reg_pofc; /* Rx Port Overrun Frame Counter */ 272 struct evcnt ev_reg_txbadfcs; /* Tx BAD FCS Counter */ 273 struct evcnt ev_reg_txdropped; /* Tx Dropped Counter */ 274 struct evcnt ev_reg_lpic; 275 276 277 /* Device Driver Errors */ 278 struct evcnt ev_drv_wdogsoft; 279 struct evcnt ev_drv_txerr; 280 struct evcnt ev_drv_rxq[MVXPE_QUEUE_SIZE]; 281 struct evcnt ev_drv_rxqe[MVXPE_QUEUE_SIZE]; 282 struct evcnt ev_drv_txq[MVXPE_QUEUE_SIZE]; 283 struct evcnt ev_drv_txqe[MVXPE_QUEUE_SIZE]; 284 }; 285 286 /* 287 * Debug 288 */ 289 #ifdef MVXPE_DEBUG 290 #define DPRINTF(fmt, ...) \ 291 do { \ 292 if (mvxpe_debug >= 1) { \ 293 printf("%s: ", __func__); \ 294 printf((fmt), ##__VA_ARGS__); \ 295 } \ 296 } while (/*CONSTCOND*/0) 297 #define DPRINTFN(level , fmt, ...) \ 298 do { \ 299 if (mvxpe_debug >= (level)) { \ 300 printf("%s: ", __func__); \ 301 printf((fmt), ##__VA_ARGS__); \ 302 } \ 303 } while (/*CONSTCOND*/0) 304 #define DPRINTDEV(dev, level, fmt, ...) \ 305 do { \ 306 if (mvxpe_debug >= (level)) { \ 307 device_printf((dev), \ 308 "%s: "fmt , __func__, ##__VA_ARGS__); \ 309 } \ 310 } while (/*CONSTCOND*/0) 311 #define DPRINTSC(sc, level, fmt, ...) \ 312 do { \ 313 device_t dev = (sc)->sc_dev; \ 314 if (mvxpe_debug >= (level)) { \ 315 device_printf(dev, \ 316 "%s: " fmt, __func__, ##__VA_ARGS__); \ 317 } \ 318 } while (/*CONSTCOND*/0) 319 #define DPRINTIFNET(ifp, level, fmt, ...) \ 320 do { \ 321 const char *xname = (ifp)->if_xname; \ 322 if (mvxpe_debug >= (level)) { \ 323 printf("%s: %s: " fmt, xname, __func__, ##__VA_ARGS__);\ 324 } \ 325 } while (/*CONSTCOND*/0) 326 #define DPRINTIFNET(ifp, level, fmt, ...) \ 327 do { \ 328 const char *xname = (ifp)->if_xname; \ 329 if (mvxpe_debug >= (level)) { \ 330 printf("%s: %s: " fmt, xname, __func__, ##__VA_ARGS__);\ 331 } \ 332 } while (/*CONSTCOND*/0) 333 #define DPRINTPRXS(level, q) \ 334 do { \ 335 uint32_t _reg = MVXPE_READ(sc, MVXPE_PRXS(q)); \ 336 if (mvxpe_debug >= (level)) { \ 337 printf("PRXS(queue %d) %#x: Occupied %d, NoOccupied %d.\n", \ 338 q, _reg, MVXPE_PRXS_GET_ODC(_reg), \ 339 MVXPE_PRXS_GET_NODC(_reg)); \ 340 } \ 341 } while (/*CONSTCOND*/0) 342 #else 343 #define DPRINTF(fmt, ...) 344 #define DPRINTFN(level, fmt, ...) 345 #define DPRINTDEV(dev, level, fmt, ...) 346 #define DPRINTSC(sc, level, fmt, ...) 347 #define DPRINTIFNET(ifp, level, fmt, ...) 348 #define DPRINTPRXS(level, reg) 349 #endif 350 351 #define KASSERT_SC_MTX(sc) \ 352 KASSERT(mutex_owned(&(sc)->sc_mtx)) 353 #define KASSERT_BM_MTX(sc) \ 354 KASSERT(mutex_owned(&(sc)->sc_bm.bm_mtx)) 355 #define KASSERT_RX_MTX(sc, q) \ 356 KASSERT(mutex_owned(&(sc)->sc_rx_ring[(q)].rx_ring_mtx)) 357 #define KASSERT_TX_MTX(sc, q) \ 358 KASSERT(mutex_owned(&(sc)->sc_tx_ring[(q)].tx_ring_mtx)) 359 360 /* 361 * Configuration parameters 362 */ 363 struct mvxpe_conf { 364 int cf_lpi; /* EEE Low Power IDLE enable */ 365 int cf_fc; /* Flow Control enable */ 366 }; 367 368 /* 369 * sysctl(9) parameters 370 */ 371 struct mvxpe_softc; 372 struct mvxpe_sysctl_queue { 373 struct mvxpe_softc *sc; 374 int rxtx; 375 int queue; 376 }; 377 #define MVXPE_SYSCTL_RX 0 378 #define MVXPE_SYSCTL_TX 1 379 380 struct mvxpe_sysctl_mib { 381 struct mvxpe_softc *sc; 382 int index; 383 uint64_t counter; 384 }; 385 386 /* 387 * Ethernet Device main context 388 */ 389 struct mvxpe_softc { 390 device_t sc_dev; 391 int sc_port; 392 uint32_t sc_version; 393 394 /* 395 * sc_mtx must be held by interface functions to/from 396 * other frameworks. interrupt hander, sysctl hander, 397 * ioctl hander, and so on. 398 */ 399 kmutex_t sc_mtx; 400 401 /* 402 * Ethernet facilities 403 */ 404 struct ethercom sc_ethercom; 405 struct mii_data sc_mii; 406 u_int8_t sc_enaddr[ETHER_ADDR_LEN]; /* station addr */ 407 int sc_if_flags; 408 int sc_wdogsoft; 409 410 /* 411 * Configuration Parameters 412 */ 413 struct mvxpe_conf sc_cf; 414 415 /* 416 * I/O Spaces 417 */ 418 bus_space_tag_t sc_iot; 419 bus_space_handle_t sc_ioh; /* all registers handle */ 420 bus_space_handle_t sc_mibh; /* mib counter handle */ 421 422 /* 423 * DMA Spaces 424 */ 425 bus_dma_tag_t sc_dmat; 426 struct mvxpe_rx_ring sc_rx_ring[MVXPE_QUEUE_SIZE]; 427 struct mvxpe_tx_ring sc_tx_ring[MVXPE_QUEUE_SIZE]; 428 int sc_tx_pending; /* total number of tx pkt */ 429 430 /* 431 * Software Buffer Manager 432 */ 433 struct mvxpbm_softc *sc_bm; 434 435 /* 436 * Maintance clock 437 */ 438 callout_t sc_tick_ch; /* tick callout */ 439 440 /* 441 * Link State control 442 */ 443 uint32_t sc_linkstate; 444 445 /* 446 * Act as Rndom source 447 */ 448 krndsource_t sc_rnd_source; 449 450 /* 451 * Sysctl interfaces 452 */ 453 struct sysctllog *sc_mvxpe_clog; 454 struct mvxpe_sysctl_queue sc_sysctl_rx_queue[MVXPE_QUEUE_SIZE]; 455 struct mvxpe_sysctl_queue sc_sysctl_tx_queue[MVXPE_QUEUE_SIZE]; 456 457 /* 458 * MIB counter 459 */ 460 size_t sc_sysctl_mib_size; 461 struct mvxpe_sysctl_mib *sc_sysctl_mib; 462 463 #ifdef MVXPE_EVENT_COUNTERS 464 /* 465 * Event counter 466 */ 467 struct mvxpe_evcnt sc_ev; 468 #endif 469 }; 470 #define MVXPE_RX_RING_MEM_VA(sc, q) \ 471 ((sc)->sc_rx_ring[(q)].rx_descriptors) 472 #define MVXPE_RX_RING_MEM_PA(sc, q) \ 473 ((sc)->sc_rx_ring[(q)].rx_descriptors_map->dm_segs[0].ds_addr) 474 #define MVXPE_RX_RING_MEM_MAP(sc, q) \ 475 ((sc)->sc_rx_ring[(q)].rx_descriptors_map) 476 #define MVXPE_RX_RING(sc, q) \ 477 (&(sc)->sc_rx_ring[(q)]) 478 #define MVXPE_RX_HANDLE(sc, q, i) \ 479 (&(sc)->sc_rx_ring[(q)].rx_handle[(i)]) 480 #define MVXPE_RX_DESC(sc, q, i) \ 481 ((sc)->sc_rx_ring[(q)].rx_handle[(i)].rxdesc_va) 482 #define MVXPE_RX_DESC_OFF(sc, q, i) \ 483 ((sc)->sc_rx_ring[(q)].rx_handle[(i)].rxdesc_off) 484 #define MVXPE_RX_PKTBUF(sc, q, i) \ 485 ((sc)->sc_rx_ring[(q)].rx_handle[(i)].chunk) 486 487 #define MVXPE_TX_RING_MEM_VA(sc, q) \ 488 ((sc)->sc_tx_ring[(q)].tx_descriptors) 489 #define MVXPE_TX_RING_MEM_PA(sc, q) \ 490 ((sc)->sc_tx_ring[(q)].tx_descriptors_map->dm_segs[0].ds_addr) 491 #define MVXPE_TX_RING_MEM_MAP(sc, q) \ 492 ((sc)->sc_tx_ring[(q)].tx_descriptors_map) 493 #define MVXPE_TX_RING(sc, q) \ 494 (&(sc)->sc_tx_ring[(q)]) 495 #define MVXPE_TX_HANDLE(sc, q, i) \ 496 (&(sc)->sc_tx_ring[(q)].tx_handle[(i)]) 497 #define MVXPE_TX_DESC(sc, q, i) \ 498 ((sc)->sc_tx_ring[(q)].tx_handle[(i)].txdesc_va) 499 #define MVXPE_TX_DESC_OFF(sc, q, i) \ 500 ((sc)->sc_tx_ring[(q)].tx_handle[(i)].txdesc_off) 501 #define MVXPE_TX_MBUF(sc, q, i) \ 502 ((sc)->sc_tx_ring[(q)].tx_handle[(i)].txdesc_mbuf) 503 #define MVXPE_TX_MAP(sc, q, i) \ 504 ((sc)->sc_tx_ring[(q)].tx_handle[(i)].txdesc_mbuf_map) 505 506 #endif /* _IF_MVXPEVAR_H_ */ 507