| | 243 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP73_LAN1, |
| | 244 | "NVIDIA nForce MCP73 Networking Adapter"}, |
| | 245 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP73_LAN2, |
| | 246 | "NVIDIA nForce MCP73 Networking Adapter"}, |
| | 247 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP73_LAN3, |
| | 248 | "NVIDIA nForce MCP73 Networking Adapter"}, |
| | 249 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP73_LAN4, |
| | 250 | "NVIDIA nForce MCP73 Networking Adapter"}, |
| | 251 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN1, |
| | 252 | "NVIDIA nForce MCP77 Networking Adapter"}, |
| | 253 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN2, |
| | 254 | "NVIDIA nForce MCP77 Networking Adapter"}, |
| | 255 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN3, |
| | 256 | "NVIDIA nForce MCP77 Networking Adapter"}, |
| | 257 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP77_LAN4, |
| | 258 | "NVIDIA nForce MCP77 Networking Adapter"}, |
| | 259 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN1, |
| | 260 | "NVIDIA nForce MCP79 Networking Adapter"}, |
| | 261 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN2, |
| | 262 | "NVIDIA nForce MCP79 Networking Adapter"}, |
| | 263 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN3, |
| | 264 | "NVIDIA nForce MCP79 Networking Adapter"}, |
| | 265 | {PCI_VENDOR_NVIDIA, PCI_PRODUCT_NVIDIA_MCP79_LAN4, |
| | 266 | "NVIDIA nForce MCP79 Networking Adapter"}, |
| 465 | | NFE_TX_FLOW_CTRL; |
| | 488 | NFE_CORRECT_MACADDR | NFE_TX_FLOW_CTRL | NFE_MIB_V2; |
| | 489 | break; |
| | 490 | case PCI_PRODUCT_NVIDIA_MCP77_LAN1: |
| | 491 | case PCI_PRODUCT_NVIDIA_MCP77_LAN2: |
| | 492 | case PCI_PRODUCT_NVIDIA_MCP77_LAN3: |
| | 493 | case PCI_PRODUCT_NVIDIA_MCP77_LAN4: |
| | 494 | /* XXX flow control */ |
| | 495 | sc->nfe_flags |= NFE_40BIT_ADDR | NFE_HW_CSUM | NFE_PWR_MGMT | |
| | 496 | NFE_CORRECT_MACADDR | NFE_MIB_V3; |
| | 497 | break; |
| | 498 | case PCI_PRODUCT_NVIDIA_MCP79_LAN1: |
| | 499 | case PCI_PRODUCT_NVIDIA_MCP79_LAN2: |
| | 500 | case PCI_PRODUCT_NVIDIA_MCP79_LAN3: |
| | 501 | case PCI_PRODUCT_NVIDIA_MCP79_LAN4: |
| | 502 | /* XXX flow control */ |
| | 503 | sc->nfe_flags |= NFE_JUMBO_SUP | NFE_40BIT_ADDR | NFE_HW_CSUM | |
| | 504 | NFE_PWR_MGMT | NFE_CORRECT_MACADDR | NFE_MIB_V3; |
| 519 | | |
| 520 | | SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), |
| 521 | | SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), |
| 522 | | OID_AUTO, "process_limit", CTLTYPE_INT | CTLFLAG_RW, |
| 523 | | &sc->nfe_process_limit, 0, sysctl_hw_nfe_proc_limit, "I", |
| 524 | | "max number of Rx events to process"); |
| 525 | | |
| 526 | | sc->nfe_process_limit = NFE_PROC_DEFAULT; |
| 527 | | error = resource_int_value(device_get_name(dev), device_get_unit(dev), |
| 528 | | "process_limit", &sc->nfe_process_limit); |
| 529 | | if (error == 0) { |
| 530 | | if (sc->nfe_process_limit < NFE_PROC_MIN || |
| 531 | | sc->nfe_process_limit > NFE_PROC_MAX) { |
| 532 | | device_printf(dev, "process_limit value out of range; " |
| 533 | | "using default: %d\n", NFE_PROC_DEFAULT); |
| 534 | | sc->nfe_process_limit = NFE_PROC_DEFAULT; |
| 535 | | } |
| 536 | | } |
| | 559 | /* Create sysctl node. */ |
| | 560 | nfe_sysctl_node(sc); |
| 985 | | /* |
| 986 | | * Allocate a jumbo buffer. |
| 987 | | */ |
| 988 | | static void * |
| 989 | | nfe_jalloc(struct nfe_softc *sc) |
| 990 | | { |
| 991 | | struct nfe_jpool_entry *entry; |
| 992 | | |
| 993 | | NFE_JLIST_LOCK(sc); |
| 994 | | |
| 995 | | entry = SLIST_FIRST(&sc->nfe_jfree_listhead); |
| 996 | | |
| 997 | | if (entry == NULL) { |
| 998 | | NFE_JLIST_UNLOCK(sc); |
| 999 | | return (NULL); |
| 1000 | | } |
| 1001 | | |
| 1002 | | SLIST_REMOVE_HEAD(&sc->nfe_jfree_listhead, jpool_entries); |
| 1003 | | SLIST_INSERT_HEAD(&sc->nfe_jinuse_listhead, entry, jpool_entries); |
| 1004 | | |
| 1005 | | NFE_JLIST_UNLOCK(sc); |
| 1006 | | |
| 1007 | | return (sc->jrxq.jslots[entry->slot]); |
| 1008 | | } |
| 1009 | | |
| 1010 | | /* |
| 1011 | | * Release a jumbo buffer. |
| 1012 | | */ |
| 1013 | | static void |
| 1014 | | nfe_jfree(void *buf, void *args) |
| 1015 | | { |
| 1016 | | struct nfe_softc *sc; |
| 1017 | | struct nfe_jpool_entry *entry; |
| 1018 | | int i; |
| 1019 | | |
| 1020 | | /* Extract the softc struct pointer. */ |
| 1021 | | sc = (struct nfe_softc *)args; |
| 1022 | | KASSERT(sc != NULL, ("%s: can't find softc pointer!", __func__)); |
| 1023 | | |
| 1024 | | NFE_JLIST_LOCK(sc); |
| 1025 | | /* Calculate the slot this buffer belongs to. */ |
| 1026 | | i = ((vm_offset_t)buf |
| 1027 | | - (vm_offset_t)sc->jrxq.jpool) / NFE_JLEN; |
| 1028 | | KASSERT(i >= 0 && i < NFE_JSLOTS, |
| 1029 | | ("%s: asked to free buffer that we don't manage!", __func__)); |
| 1030 | | |
| 1031 | | entry = SLIST_FIRST(&sc->nfe_jinuse_listhead); |
| 1032 | | KASSERT(entry != NULL, ("%s: buffer not in use!", __func__)); |
| 1033 | | entry->slot = i; |
| 1034 | | SLIST_REMOVE_HEAD(&sc->nfe_jinuse_listhead, jpool_entries); |
| 1035 | | SLIST_INSERT_HEAD(&sc->nfe_jfree_listhead, entry, jpool_entries); |
| 1036 | | if (SLIST_EMPTY(&sc->nfe_jinuse_listhead)) |
| 1037 | | wakeup(sc); |
| 1038 | | |
| 1039 | | NFE_JLIST_UNLOCK(sc); |
| 1040 | | } |
| 1041 | | |
| 1190 | | /* Create DMA tag for jumbo buffer blocks. */ |
| 1191 | | error = bus_dma_tag_create(sc->nfe_parent_tag, |
| 1192 | | PAGE_SIZE, 0, /* alignment, boundary */ |
| 1193 | | BUS_SPACE_MAXADDR, /* lowaddr */ |
| 1194 | | BUS_SPACE_MAXADDR, /* highaddr */ |
| 1195 | | NULL, NULL, /* filter, filterarg */ |
| 1196 | | NFE_JMEM, /* maxsize */ |
| 1197 | | 1, /* nsegments */ |
| 1198 | | NFE_JMEM, /* maxsegsize */ |
| 1199 | | 0, /* flags */ |
| 1200 | | NULL, NULL, /* lockfunc, lockarg */ |
| 1201 | | &ring->jrx_jumbo_tag); |
| 1202 | | if (error != 0) { |
| 1203 | | device_printf(sc->nfe_dev, |
| 1204 | | "could not create jumbo Rx buffer block DMA tag\n"); |
| 1205 | | goto fail; |
| 1206 | | } |
| 1207 | | |
| 1270 | | /* Allocate DMA'able memory and load the DMA map for jumbo buf. */ |
| 1271 | | error = bus_dmamem_alloc(ring->jrx_jumbo_tag, (void **)&ring->jpool, |
| 1272 | | BUS_DMA_WAITOK | BUS_DMA_COHERENT | BUS_DMA_ZERO, |
| 1273 | | &ring->jrx_jumbo_map); |
| 1274 | | if (error != 0) { |
| 1275 | | device_printf(sc->nfe_dev, |
| 1276 | | "could not allocate DMA'able memory for jumbo pool\n"); |
| 1277 | | goto fail; |
| 1278 | | } |
| 1279 | | |
| 1280 | | ctx.nfe_busaddr = 0; |
| 1281 | | error = bus_dmamap_load(ring->jrx_jumbo_tag, ring->jrx_jumbo_map, |
| 1282 | | ring->jpool, NFE_JMEM, nfe_dma_map_segs, &ctx, 0); |
| 1283 | | if (error != 0) { |
| 1284 | | device_printf(sc->nfe_dev, |
| 1285 | | "could not load DMA'able memory for jumbo pool\n"); |
| 1286 | | goto fail; |
| 1287 | | } |
| 1288 | | |
| 1289 | | /* |
| 1290 | | * Now divide it up into 9K pieces and save the addresses |
| 1291 | | * in an array. |
| 1292 | | */ |
| 1293 | | ptr = ring->jpool; |
| 1294 | | for (i = 0; i < NFE_JSLOTS; i++) { |
| 1295 | | ring->jslots[i] = ptr; |
| 1296 | | ptr += NFE_JLEN; |
| 1297 | | entry = malloc(sizeof(struct nfe_jpool_entry), M_DEVBUF, |
| 1298 | | M_WAITOK); |
| 1299 | | if (entry == NULL) { |
| 1300 | | device_printf(sc->nfe_dev, |
| 1301 | | "no memory for jumbo buffers!\n"); |
| 1302 | | error = ENOMEM; |
| 1303 | | goto fail; |
| 1304 | | } |
| 1305 | | entry->slot = i; |
| 1306 | | SLIST_INSERT_HEAD(&sc->nfe_jfree_listhead, entry, |
| 1307 | | jpool_entries); |
| 1308 | | } |
| 1309 | | |
| 1441 | | |
| 1442 | | NFE_JLIST_LOCK(sc); |
| 1443 | | while ((entry = SLIST_FIRST(&sc->nfe_jinuse_listhead))) { |
| 1444 | | device_printf(sc->nfe_dev, |
| 1445 | | "asked to free buffer that is in use!\n"); |
| 1446 | | SLIST_REMOVE_HEAD(&sc->nfe_jinuse_listhead, jpool_entries); |
| 1447 | | SLIST_INSERT_HEAD(&sc->nfe_jfree_listhead, entry, |
| 1448 | | jpool_entries); |
| 1449 | | } |
| 1450 | | |
| 1451 | | while (!SLIST_EMPTY(&sc->nfe_jfree_listhead)) { |
| 1452 | | entry = SLIST_FIRST(&sc->nfe_jfree_listhead); |
| 1453 | | SLIST_REMOVE_HEAD(&sc->nfe_jfree_listhead, jpool_entries); |
| 1454 | | free(entry, M_DEVBUF); |
| 1455 | | } |
| 1456 | | NFE_JLIST_UNLOCK(sc); |
| 2440 | | /* |
| 2441 | | * It's copy of ath_defrag(ath(4)). |
| 2442 | | * |
| 2443 | | * Defragment an mbuf chain, returning at most maxfrags separate |
| 2444 | | * mbufs+clusters. If this is not possible NULL is returned and |
| 2445 | | * the original mbuf chain is left in it's present (potentially |
| 2446 | | * modified) state. We use two techniques: collapsing consecutive |
| 2447 | | * mbufs and replacing consecutive mbufs by a cluster. |
| 2448 | | */ |
| 2449 | | static struct mbuf * |
| 2450 | | nfe_defrag(struct mbuf *m0, int how, int maxfrags) |
| 2451 | | { |
| 2452 | | struct mbuf *m, *n, *n2, **prev; |
| 2453 | | u_int curfrags; |
| 2454 | | |
| 2455 | | /* |
| 2456 | | * Calculate the current number of frags. |
| 2457 | | */ |
| 2458 | | curfrags = 0; |
| 2459 | | for (m = m0; m != NULL; m = m->m_next) |
| 2460 | | curfrags++; |
| 2461 | | /* |
| 2462 | | * First, try to collapse mbufs. Note that we always collapse |
| 2463 | | * towards the front so we don't need to deal with moving the |
| 2464 | | * pkthdr. This may be suboptimal if the first mbuf has much |
| 2465 | | * less data than the following. |
| 2466 | | */ |
| 2467 | | m = m0; |
| 2468 | | again: |
| 2469 | | for (;;) { |
| 2470 | | n = m->m_next; |
| 2471 | | if (n == NULL) |
| 2472 | | break; |
| 2473 | | if ((m->m_flags & M_RDONLY) == 0 && |
| 2474 | | n->m_len < M_TRAILINGSPACE(m)) { |
| 2475 | | bcopy(mtod(n, void *), mtod(m, char *) + m->m_len, |
| 2476 | | n->m_len); |
| 2477 | | m->m_len += n->m_len; |
| 2478 | | m->m_next = n->m_next; |
| 2479 | | m_free(n); |
| 2480 | | if (--curfrags <= maxfrags) |
| 2481 | | return (m0); |
| 2482 | | } else |
| 2483 | | m = n; |
| 2484 | | } |
| 2485 | | KASSERT(maxfrags > 1, |
| 2486 | | ("maxfrags %u, but normal collapse failed", maxfrags)); |
| 2487 | | /* |
| 2488 | | * Collapse consecutive mbufs to a cluster. |
| 2489 | | */ |
| 2490 | | prev = &m0->m_next; /* NB: not the first mbuf */ |
| 2491 | | while ((n = *prev) != NULL) { |
| 2492 | | if ((n2 = n->m_next) != NULL && |
| 2493 | | n->m_len + n2->m_len < MCLBYTES) { |
| 2494 | | m = m_getcl(how, MT_DATA, 0); |
| 2495 | | if (m == NULL) |
| 2496 | | goto bad; |
| 2497 | | bcopy(mtod(n, void *), mtod(m, void *), n->m_len); |
| 2498 | | bcopy(mtod(n2, void *), mtod(m, char *) + n->m_len, |
| 2499 | | n2->m_len); |
| 2500 | | m->m_len = n->m_len + n2->m_len; |
| 2501 | | m->m_next = n2->m_next; |
| 2502 | | *prev = m; |
| 2503 | | m_free(n); |
| 2504 | | m_free(n2); |
| 2505 | | if (--curfrags <= maxfrags) /* +1 cl -2 mbufs */ |
| 2506 | | return m0; |
| 2507 | | /* |
| 2508 | | * Still not there, try the normal collapse |
| 2509 | | * again before we allocate another cluster. |
| 2510 | | */ |
| 2511 | | goto again; |
| 2512 | | } |
| 2513 | | prev = &n->m_next; |
| 2514 | | } |
| 2515 | | /* |
| 2516 | | * No place where we can collapse to a cluster; punt. |
| 2517 | | * This can occur if, for example, you request 2 frags |
| 2518 | | * but the packet requires that both be clusters (we |
| 2519 | | * never reallocate the first mbuf to avoid moving the |
| 2520 | | * packet header). |
| 2521 | | */ |
| 2522 | | bad: |
| 2523 | | return (NULL); |
| 2524 | | } |
| 2525 | | |
| 2526 | | |
| | 3011 | |
| | 3012 | |
| | 3013 | #define NFE_SYSCTL_STAT_ADD32(c, h, n, p, d) \ |
| | 3014 | SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d) |
| | 3015 | #define NFE_SYSCTL_STAT_ADD64(c, h, n, p, d) \ |
| | 3016 | SYSCTL_ADD_QUAD(c, h, OID_AUTO, n, CTLFLAG_RD, p, d) |
| | 3017 | |
| | 3018 | static void |
| | 3019 | nfe_sysctl_node(struct nfe_softc *sc) |
| | 3020 | { |
| | 3021 | struct sysctl_ctx_list *ctx; |
| | 3022 | struct sysctl_oid_list *child, *parent; |
| | 3023 | struct sysctl_oid *tree; |
| | 3024 | struct nfe_hw_stats *stats; |
| | 3025 | int error; |
| | 3026 | |
| | 3027 | stats = &sc->nfe_stats; |
| | 3028 | ctx = device_get_sysctl_ctx(sc->nfe_dev); |
| | 3029 | child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->nfe_dev)); |
| | 3030 | SYSCTL_ADD_PROC(ctx, child, |
| | 3031 | OID_AUTO, "process_limit", CTLTYPE_INT | CTLFLAG_RW, |
| | 3032 | &sc->nfe_process_limit, 0, sysctl_hw_nfe_proc_limit, "I", |
| | 3033 | "max number of Rx events to process"); |
| | 3034 | |
| | 3035 | sc->nfe_process_limit = NFE_PROC_DEFAULT; |
| | 3036 | error = resource_int_value(device_get_name(sc->nfe_dev), |
| | 3037 | device_get_unit(sc->nfe_dev), "process_limit", |
| | 3038 | &sc->nfe_process_limit); |
| | 3039 | if (error == 0) { |
| | 3040 | if (sc->nfe_process_limit < NFE_PROC_MIN || |
| | 3041 | sc->nfe_process_limit > NFE_PROC_MAX) { |
| | 3042 | device_printf(sc->nfe_dev, |
| | 3043 | "process_limit value out of range; " |
| | 3044 | "using default: %d\n", NFE_PROC_DEFAULT); |
| | 3045 | sc->nfe_process_limit = NFE_PROC_DEFAULT; |
| | 3046 | |