Deleted Added
sdiff udiff text old ( 170789 ) new ( 170869 )
full compact
1/**************************************************************************
2
3Copyright (c) 2007, Chelsio Inc.
4All rights reserved.
5
6Redistribution and use in source and binary forms, with or without
7modification, are permitted provided that the following conditions are met:
8

--- 14 unchanged lines hidden (view full) ---

23INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26POSSIBILITY OF SUCH DAMAGE.
27
28***************************************************************************/
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/dev/cxgb/cxgb_main.c 170869 2007-06-17 04:33:38Z kmacy $");
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/kernel.h>
36#include <sys/bus.h>
37#include <sys/module.h>
38#include <sys/pciio.h>
39#include <sys/conf.h>

--- 51 unchanged lines hidden (view full) ---

91static int cxgb_ioctl(struct ifnet *, unsigned long, caddr_t);
92static void cxgb_start(struct ifnet *);
93static void cxgb_start_proc(void *, int ncount);
94static int cxgb_media_change(struct ifnet *);
95static void cxgb_media_status(struct ifnet *, struct ifmediareq *);
96static int setup_sge_qsets(adapter_t *);
97static void cxgb_async_intr(void *);
98static void cxgb_ext_intr_handler(void *, int);
99static void cxgb_tick_handler(void *, int);
100static void cxgb_down_locked(struct adapter *sc);
101static void cxgb_tick(void *);
102static void setup_rss(adapter_t *sc);
103
104/* Attachment glue for the PCI controller end of the device. Each port of
105 * the device is attached separately, as defined later.
106 */
107static int cxgb_controller_probe(device_t);
108static int cxgb_controller_attach(device_t);

--- 205 unchanged lines hidden (view full) ---

314 FW_VERSION_MINOR, FW_VERSION_MICRO);
315
316 fw = firmware_get(buf);
317
318 if (fw == NULL) {
319 device_printf(sc->dev, "Could not find firmware image %s\n", buf);
320 return (ENOENT);
321 }
322 status = t3_load_fw(sc, (const uint8_t *)fw->data, fw->datasize);
323
324 firmware_put(fw, FIRMWARE_UNLOAD);
325
326 return (status);
327}
328
329static int
330cxgb_controller_attach(device_t dev)
331{
332 device_t child;
333 const struct adapter_info *ai;
334 struct adapter *sc;
335 int i, reg, msi_needed, error = 0;
336 uint32_t vers;
337 int port_qsets = 1;
338
339 sc = device_get_softc(dev);
340 sc->dev = dev;
341 sc->msi_count = 0;
342
343 /* find the PCIe link width and set max read request to 4KB*/
344 if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
345 uint16_t lnk, pectl;
346 lnk = pci_read_config(dev, reg + 0x12, 2);

--- 16 unchanged lines hidden (view full) ---

363 */
364 sc->regs_rid = PCIR_BAR(0);
365 if ((sc->regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
366 &sc->regs_rid, RF_ACTIVE)) == NULL) {
367 device_printf(dev, "Cannot allocate BAR\n");
368 return (ENXIO);
369 }
370
371 snprintf(sc->lockbuf, ADAPTER_LOCK_NAME_LEN, "cxgb controller lock %d",
372 device_get_unit(dev));
373 ADAPTER_LOCK_INIT(sc, sc->lockbuf);
374
375 snprintf(sc->reglockbuf, ADAPTER_LOCK_NAME_LEN, "SGE reg lock %d",
376 device_get_unit(dev));
377 snprintf(sc->mdiolockbuf, ADAPTER_LOCK_NAME_LEN, "cxgb mdio lock %d",
378 device_get_unit(dev));
379 snprintf(sc->elmerlockbuf, ADAPTER_LOCK_NAME_LEN, "cxgb elmer lock %d",
380 device_get_unit(dev));
381
382 MTX_INIT(&sc->sge.reg_lock, sc->reglockbuf, NULL, MTX_DEF);
383 MTX_INIT(&sc->mdio_lock, sc->mdiolockbuf, NULL, MTX_DEF);
384 MTX_INIT(&sc->elmer_lock, sc->elmerlockbuf, NULL, MTX_DEF);
385
386 sc->bt = rman_get_bustag(sc->regs_res);
387 sc->bh = rman_get_bushandle(sc->regs_res);
388 sc->mmio_len = rman_get_size(sc->regs_res);
389
390 ai = cxgb_get_adapter_info(dev);
391 if (t3_prep_adapter(sc, ai, 1) < 0) {
392 printf("prep adapter failed\n");
393 error = ENODEV;

--- 60 unchanged lines hidden (view full) ---

454 if (sc->tq == NULL) {
455 device_printf(dev, "failed to allocate controller task queue\n");
456 goto out;
457 }
458
459 taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s taskq",
460 device_get_nameunit(dev));
461 TASK_INIT(&sc->ext_intr_task, 0, cxgb_ext_intr_handler, sc);
462 TASK_INIT(&sc->tick_task, 0, cxgb_tick_handler, sc);
463
464
465 /* Create a periodic callout for checking adapter status */
466 callout_init(&sc->cxgb_tick_ch, TRUE);
467
468 if (t3_check_fw_version(sc) != 0) {
469 /*
470 * Warn user that a firmware update will be attempted in init.
471 */
472 device_printf(dev, "firmware needs to be updated to version %d.%d.%d\n",
473 FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
474 sc->flags &= ~FW_UPTODATE;

--- 67 unchanged lines hidden (view full) ---

542 return (0);
543}
544
545static void
546cxgb_free(struct adapter *sc)
547{
548 int i;
549
550 ADAPTER_LOCK(sc);
551 /*
552 * drops the lock
553 */
554 cxgb_down_locked(sc);
555
556#ifdef MSI_SUPPORTED
557 if (sc->flags & (USING_MSI | USING_MSIX)) {
558 device_printf(sc->dev, "releasing msi message(s)\n");
559 pci_release_msi(sc->dev);
560 } else {
561 device_printf(sc->dev, "no msi message to release\n");
562 }
563#endif
564 if (sc->msix_regs_res != NULL) {
565 bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->msix_regs_rid,
566 sc->msix_regs_res);
567 }
568
569 t3_sge_deinit_sw(sc);
570
571 if (sc->tq != NULL) {
572 taskqueue_drain(sc->tq, &sc->ext_intr_task);
573 taskqueue_drain(sc->tq, &sc->tick_task);
574 taskqueue_free(sc->tq);
575 }
576
577 tsleep(&sc, 0, "cxgb unload", hz);
578
579 for (i = 0; i < (sc)->params.nports; ++i) {
580 if (sc->portdev[i] != NULL)
581 device_delete_child(sc->dev, sc->portdev[i]);
582 }
583
584 bus_generic_detach(sc->dev);
585#ifdef notyet
586 if (is_offload(sc)) {
587 cxgb_adapter_unofld(sc);
588 if (isset(&sc->open_device_map, OFFLOAD_DEVMAP_BIT))
589 offload_close(&sc->tdev);
590 }
591#endif
592 t3_free_sge_resources(sc);
593 t3_sge_free(sc);
594
595 cxgb_offload_exit();
596
597 if (sc->regs_res != NULL)
598 bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->regs_rid,
599 sc->regs_res);
600
601 MTX_DESTROY(&sc->mdio_lock);
602 MTX_DESTROY(&sc->sge.reg_lock);
603 MTX_DESTROY(&sc->elmer_lock);
604 ADAPTER_LOCK_DEINIT(sc);
605
606 return;
607}
608
609/**
610 * setup_sge_qsets - configure SGE Tx/Rx/response queues
611 * @sc: the controller softc
612 *

--- 155 unchanged lines hidden (view full) ---

768
769
770static int
771cxgb_port_attach(device_t dev)
772{
773 struct port_info *p;
774 struct ifnet *ifp;
775 int err, media_flags;
776
777 p = device_get_softc(dev);
778
779 snprintf(p->lockbuf, PORT_NAME_LEN, "cxgb port lock %d:%d",
780 device_get_unit(device_get_parent(dev)), p->port);
781 PORT_LOCK_INIT(p, p->lockbuf);
782
783 /* Allocate an ifnet object and set it up */
784 ifp = p->ifp = if_alloc(IFT_ETHER);
785 if (ifp == NULL) {
786 device_printf(dev, "Cannot allocate ifnet\n");
787 return (ENOMEM);
788 }
789

--- 54 unchanged lines hidden (view full) ---

844 ifmedia_add(&p->media, media_flags, 0, NULL);
845 ifmedia_set(&p->media, media_flags);
846 } else {
847 ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL);
848 ifmedia_set(&p->media, IFM_ETHER | IFM_AUTO);
849 }
850
851
852 snprintf(p->taskqbuf, TASKQ_NAME_LEN, "cxgb_port_taskq%d", p->port);
853#ifdef TASKQUEUE_CURRENT
854 /* Create a port for handling TX without starvation */
855 p->tq = taskqueue_create(p->taskqbuf, M_NOWAIT,
856 taskqueue_thread_enqueue, &p->tq);
857#else
858 /* Create a port for handling TX without starvation */
859 p->tq = taskqueue_create_fast(buf, M_NOWAIT,
860 taskqueue_thread_enqueue, &p->tq);
861#endif
862
863 if (p->tq == NULL) {

--- 16 unchanged lines hidden (view full) ---

880
881 p = device_get_softc(dev);
882
883 PORT_LOCK(p);
884 if (p->ifp->if_drv_flags & IFF_DRV_RUNNING)
885 cxgb_stop_locked(p);
886 PORT_UNLOCK(p);
887
888 if (p->tq != NULL) {
889 taskqueue_drain(p->tq, &p->start_task);
890 taskqueue_free(p->tq);
891 p->tq = NULL;
892 }
893
894 PORT_LOCK_DEINIT(p);
895 ether_ifdetach(p->ifp);
896 if_free(p->ifp);
897
898 if (p->port_cdev != NULL)
899 destroy_dev(p->port_cdev);
900
901 return (0);
902}

--- 375 unchanged lines hidden (view full) ---

1278 goto out;
1279}
1280
1281
1282/*
1283 * Release resources when all the ports and offloading have been stopped.
1284 */
1285static void
1286cxgb_down_locked(struct adapter *sc)
1287{
1288 int i;
1289
1290 t3_sge_stop(sc);
1291 t3_intr_disable(sc);
1292
1293 if (sc->intr_tag != NULL) {
1294 bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag);
1295 sc->intr_tag = NULL;
1296 }
1297 if (sc->irq_res != NULL) {
1298 device_printf(sc->dev, "de-allocating interrupt irq_rid=%d irq_res=%p\n",
1299 sc->irq_rid, sc->irq_res);
1300 bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
1301 sc->irq_res);
1302 sc->irq_res = NULL;
1303 }
1304
1305 if (sc->flags & USING_MSIX)
1306 cxgb_teardown_msix(sc);
1307 ADAPTER_UNLOCK(sc);
1308
1309 callout_drain(&sc->cxgb_tick_ch);
1310 callout_drain(&sc->sge_timer_ch);
1311
1312 if (sc->tq != NULL)
1313 taskqueue_drain(sc->tq, &sc->slow_intr_task);
1314 for (i = 0; i < sc->params.nports; i++)
1315 if (sc->port[i].tq != NULL)
1316 taskqueue_drain(sc->port[i].tq, &sc->port[i].timer_reclaim_task);
1317
1318}
1319

--- 53 unchanged lines hidden (view full) ---

1373
1374 /* Call back all registered clients */
1375 cxgb_remove_clients(tdev);
1376 tdev->lldev = NULL;
1377 cxgb_set_dummy_ops(tdev);
1378 t3_tp_set_offload_mode(adapter, 0);
1379 clrbit(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT);
1380
1381 if (!adapter->open_device_map)
1382 cxgb_down(adapter);
1383
1384 cxgb_offload_deactivate(adapter);
1385 return (0);
1386}
1387#endif
1388
1389static void
1390cxgb_init(void *arg)

--- 7 unchanged lines hidden (view full) ---

1398
1399static void
1400cxgb_init_locked(struct port_info *p)
1401{
1402 struct ifnet *ifp;
1403 adapter_t *sc = p->adapter;
1404 int err;
1405
1406 PORT_LOCK_ASSERT_OWNED(p);
1407 ifp = p->ifp;
1408
1409 ADAPTER_LOCK(p->adapter);
1410 if ((sc->open_device_map == 0) && ((err = cxgb_up(sc)) < 0)) {
1411 ADAPTER_UNLOCK(p->adapter);
1412 cxgb_stop_locked(p);
1413 return;
1414 }
1415 if (p->adapter->open_device_map == 0) {
1416 t3_intr_clear(sc);
1417 t3_sge_init_adapter(sc);
1418 }
1419 setbit(&p->adapter->open_device_map, p->port);
1420 ADAPTER_UNLOCK(p->adapter);
1421
1422 if (is_offload(sc) && !ofld_disable) {
1423 err = offload_open(p);
1424 if (err)
1425 log(LOG_WARNING,
1426 "Could not initialize offload capabilities\n");
1427 }
1428 cxgb_link_start(p);
1429 t3_link_changed(sc, p->port);
1430 ifp->if_baudrate = p->link_config.speed * 1000000;
1431
1432 t3_port_intr_enable(sc, p->port);
1433
1434 callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
1435 cxgb_tick, sc);
1436
1437 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1438 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1439}
1440
1441static void
1442cxgb_set_rxmode(struct port_info *p)
1443{
1444 struct t3_rx_mode rm;
1445 struct cmac *mac = &p->mac;
1446
1447 PORT_LOCK_ASSERT_OWNED(p);
1448
1449 t3_init_rx_mode(&rm, p);
1450 t3_mac_set_rx_mode(mac, &rm);
1451}
1452
1453static void
1454cxgb_stop_locked(struct port_info *p)
1455{
1456 struct ifnet *ifp;
1457
1458 PORT_LOCK_ASSERT_OWNED(p);
1459 ADAPTER_LOCK_ASSERT_NOTOWNED(p->adapter);
1460
1461 ifp = p->ifp;
1462
1463 t3_port_intr_disable(p->adapter, p->port);
1464 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1465 p->phy.ops->power_down(&p->phy, 1);
1466 t3_mac_disable(&p->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
1467
1468 ADAPTER_LOCK(p->adapter);
1469 clrbit(&p->adapter->open_device_map, p->port);
1470
1471
1472 if (p->adapter->open_device_map == 0) {
1473 cxgb_down_locked(p->adapter);
1474 } else
1475 ADAPTER_UNLOCK(p->adapter);
1476
1477}
1478
1479static int
1480cxgb_set_mtu(struct port_info *p, int mtu)
1481{
1482 struct ifnet *ifp = p->ifp;
1483 int error = 0;
1484

--- 36 unchanged lines hidden (view full) ---

1521 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1522 cxgb_init_locked(p);
1523 arp_ifinit(ifp, ifa);
1524 } else
1525 error = ether_ioctl(ifp, command, data);
1526 PORT_UNLOCK(p);
1527 break;
1528 case SIOCSIFFLAGS:
1529 callout_drain(&p->adapter->cxgb_tick_ch);
1530 PORT_LOCK(p);
1531 if (ifp->if_flags & IFF_UP) {
1532 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1533 flags = p->if_flags;
1534 if (((ifp->if_flags ^ flags) & IFF_PROMISC) ||
1535 ((ifp->if_flags ^ flags) & IFF_ALLMULTI))
1536 cxgb_set_rxmode(p);
1537 } else
1538 cxgb_init_locked(p);
1539 p->if_flags = ifp->if_flags;
1540 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1541 cxgb_stop_locked(p);
1542
1543 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1544 adapter_t *sc = p->adapter;
1545 callout_reset(&sc->cxgb_tick_ch,
1546 sc->params.stats_update_period * hz,
1547 cxgb_tick, sc);
1548 }
1549 PORT_UNLOCK(p);
1550 break;
1551 case SIOCSIFMEDIA:
1552 case SIOCGIFMEDIA:
1553 error = ifmedia_ioctl(ifp, ifr, &p->media, command);
1554 break;
1555 case SIOCSIFCAP:

--- 198 unchanged lines hidden (view full) ---

1754
1755static void
1756cxgb_async_intr(void *data)
1757{
1758 adapter_t *sc = data;
1759
1760 if (cxgb_debug)
1761 device_printf(sc->dev, "cxgb_async_intr\n");
1762 /*
1763 * May need to sleep - defer to taskqueue
1764 */
1765 taskqueue_enqueue(sc->tq, &sc->slow_intr_task);
1766}
1767
1768static void
1769cxgb_ext_intr_handler(void *arg, int count)
1770{
1771 adapter_t *sc = (adapter_t *)arg;
1772
1773 if (cxgb_debug)

--- 59 unchanged lines hidden (view full) ---

1833 PORT_UNLOCK(p);
1834 }
1835}
1836
1837static void
1838cxgb_tick(void *arg)
1839{
1840 adapter_t *sc = (adapter_t *)arg;
1841
1842 taskqueue_enqueue(sc->tq, &sc->tick_task);
1843
1844 if (sc->open_device_map != 0)
1845 callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
1846 cxgb_tick, sc);
1847}
1848
1849static void
1850cxgb_tick_handler(void *arg, int count)
1851{
1852 adapter_t *sc = (adapter_t *)arg;
1853 const struct adapter_params *p = &sc->params;
1854
1855 ADAPTER_LOCK(sc);
1856 if (p->linkpoll_period)
1857 check_link_status(sc);
1858
1859 /*
1860 * adapter lock can currently only be acquire after the
1861 * port lock
1862 */
1863 ADAPTER_UNLOCK(sc);
1864
1865 if (p->rev == T3_REV_B2)

--- 466 unchanged lines hidden ---