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 170789 2007-06-15 20:02:02Z 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_down(struct adapter *sc);
100static void cxgb_tick(void *);
101static void setup_rss(adapter_t *sc);
102
103/* Attachment glue for the PCI controller end of the device. Each port of
104 * the device is attached separately, as defined later.
105 */
106static int cxgb_controller_probe(device_t);
107static int cxgb_controller_attach(device_t);

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

313 FW_VERSION_MINOR, FW_VERSION_MICRO);
314
315 fw = firmware_get(buf);
316
317 if (fw == NULL) {
318 device_printf(sc->dev, "Could not find firmware image %s\n", buf);
319 return (ENOENT);
320 }
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 mtx_init(&sc->sge.reg_lock, "SGE reg lock", NULL, MTX_DEF);
372 mtx_init(&sc->lock, "cxgb controller lock", NULL, MTX_DEF);
373 mtx_init(&sc->mdio_lock, "cxgb mdio", NULL, MTX_DEF);
374 mtx_init(&sc->elmer_lock, "cxgb elmer", NULL, MTX_DEF);
375
376 sc->bt = rman_get_bustag(sc->regs_res);
377 sc->bh = rman_get_bushandle(sc->regs_res);
378 sc->mmio_len = rman_get_size(sc->regs_res);
379
380 ai = cxgb_get_adapter_info(dev);
381 if (t3_prep_adapter(sc, ai, 1) < 0) {
382 printf("prep adapter failed\n");
383 error = ENODEV;

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

444 if (sc->tq == NULL) {
445 device_printf(dev, "failed to allocate controller task queue\n");
446 goto out;
447 }
448
449 taskqueue_start_threads(&sc->tq, 1, PI_NET, "%s taskq",
450 device_get_nameunit(dev));
451 TASK_INIT(&sc->ext_intr_task, 0, cxgb_ext_intr_handler, sc);
452
453
454 /* Create a periodic callout for checking adapter status */
455 callout_init_mtx(&sc->cxgb_tick_ch, &sc->lock, CALLOUT_RETURNUNLOCKED);
456
457 if (t3_check_fw_version(sc) != 0) {
458 /*
459 * Warn user that a firmware update will be attempted in init.
460 */
461 device_printf(dev, "firmware needs to be updated to version %d.%d.%d\n",
462 FW_VERSION_MAJOR, FW_VERSION_MINOR, FW_VERSION_MICRO);
463 sc->flags &= ~FW_UPTODATE;

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

531 return (0);
532}
533
534static void
535cxgb_free(struct adapter *sc)
536{
537 int i;
538
539 cxgb_down(sc);
540
541#ifdef MSI_SUPPORTED
542 if (sc->flags & (USING_MSI | USING_MSIX)) {
543 device_printf(sc->dev, "releasing msi message(s)\n");
544 pci_release_msi(sc->dev);
545 } else {
546 device_printf(sc->dev, "no msi message to release\n");
547 }
548#endif
549 if (sc->msix_regs_res != NULL) {
550 bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->msix_regs_rid,
551 sc->msix_regs_res);
552 }
553
554 /*
555 * XXX need to drain the ifq by hand until
556 * it is taught about mbuf iovecs
557 */
558 callout_drain(&sc->cxgb_tick_ch);
559
560 t3_sge_deinit_sw(sc);
561
562 if (sc->tq != NULL) {
563 taskqueue_drain(sc->tq, &sc->ext_intr_task);
564 taskqueue_free(sc->tq);
565 }
566
567 for (i = 0; i < (sc)->params.nports; ++i) {
568 if (sc->portdev[i] != NULL)
569 device_delete_child(sc->dev, sc->portdev[i]);
570 }
571
572 bus_generic_detach(sc->dev);
573#ifdef notyet
574 if (is_offload(sc)) {
575 cxgb_adapter_unofld(sc);
576 if (isset(&sc->open_device_map, OFFLOAD_DEVMAP_BIT))
577 offload_close(&sc->tdev);
578 }
579#endif
580 t3_free_sge_resources(sc);
581 t3_sge_free(sc);
582
583 if (sc->regs_res != NULL)
584 bus_release_resource(sc->dev, SYS_RES_MEMORY, sc->regs_rid,
585 sc->regs_res);
586
587 mtx_destroy(&sc->mdio_lock);
588 mtx_destroy(&sc->sge.reg_lock);
589 mtx_destroy(&sc->lock);
590
591 return;
592}
593
594/**
595 * setup_sge_qsets - configure SGE Tx/Rx/response queues
596 * @sc: the controller softc
597 *

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

753
754
755static int
756cxgb_port_attach(device_t dev)
757{
758 struct port_info *p;
759 struct ifnet *ifp;
760 int err, media_flags;
761 char buf[64];
762
763 p = device_get_softc(dev);
764
765 snprintf(buf, sizeof(buf), "cxgb port %d", p->port);
766 mtx_init(&p->lock, buf, 0, MTX_DEF);
767
768 /* Allocate an ifnet object and set it up */
769 ifp = p->ifp = if_alloc(IFT_ETHER);
770 if (ifp == NULL) {
771 device_printf(dev, "Cannot allocate ifnet\n");
772 return (ENOMEM);
773 }
774

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

829 ifmedia_add(&p->media, media_flags, 0, NULL);
830 ifmedia_set(&p->media, media_flags);
831 } else {
832 ifmedia_add(&p->media, IFM_ETHER | IFM_AUTO, 0, NULL);
833 ifmedia_set(&p->media, IFM_ETHER | IFM_AUTO);
834 }
835
836
837 snprintf(buf, sizeof(buf), "cxgb_port_taskq%d", p->port);
838#ifdef TASKQUEUE_CURRENT
839 /* Create a port for handling TX without starvation */
840 p->tq = taskqueue_create(buf, M_NOWAIT,
841 taskqueue_thread_enqueue, &p->tq);
842#else
843 /* Create a port for handling TX without starvation */
844 p->tq = taskqueue_create_fast(buf, M_NOWAIT,
845 taskqueue_thread_enqueue, &p->tq);
846#endif
847
848 if (p->tq == NULL) {

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

865
866 p = device_get_softc(dev);
867
868 PORT_LOCK(p);
869 if (p->ifp->if_drv_flags & IFF_DRV_RUNNING)
870 cxgb_stop_locked(p);
871 PORT_UNLOCK(p);
872
873 mtx_destroy(&p->lock);
874 if (p->tq != NULL) {
875 taskqueue_drain(p->tq, &p->start_task);
876 taskqueue_free(p->tq);
877 p->tq = NULL;
878 }
879
880 ether_ifdetach(p->ifp);
881 if_free(p->ifp);
882
883 if (p->port_cdev != NULL)
884 destroy_dev(p->port_cdev);
885
886 return (0);
887}

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

1263 goto out;
1264}
1265
1266
1267/*
1268 * Release resources when all the ports and offloading have been stopped.
1269 */
1270static void
1271cxgb_down(struct adapter *sc)
1272{
1273 int i;
1274
1275 t3_sge_stop(sc);
1276 ADAPTER_LOCK(sc);
1277 t3_intr_disable(sc);
1278 ADAPTER_UNLOCK(sc);
1279
1280
1281 if (sc->intr_tag != NULL) {
1282 bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag);
1283 sc->intr_tag = NULL;
1284 }
1285 if (sc->irq_res != NULL) {
1286 device_printf(sc->dev, "de-allocating interrupt irq_rid=%d irq_res=%p\n",
1287 sc->irq_rid, sc->irq_res);
1288 bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid,
1289 sc->irq_res);
1290 sc->irq_res = NULL;
1291 }
1292
1293 if (sc->flags & USING_MSIX)
1294 cxgb_teardown_msix(sc);
1295
1296 callout_drain(&sc->sge_timer_ch);
1297 if (sc->tq != NULL)
1298 taskqueue_drain(sc->tq, &sc->slow_intr_task);
1299 for (i = 0; i < sc->params.nports; i++)
1300 if (sc->port[i].tq != NULL)
1301 taskqueue_drain(sc->port[i].tq, &sc->port[i].timer_reclaim_task);
1302
1303}
1304

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

1358
1359 /* Call back all registered clients */
1360 cxgb_remove_clients(tdev);
1361 tdev->lldev = NULL;
1362 cxgb_set_dummy_ops(tdev);
1363 t3_tp_set_offload_mode(adapter, 0);
1364 clrbit(&adapter->open_device_map, OFFLOAD_DEVMAP_BIT);
1365
1366 ADAPTER_LOCK(adapter);
1367 if (!adapter->open_device_map)
1368 cxgb_down(adapter);
1369 ADAPTER_UNLOCK(adapter);
1370
1371 cxgb_offload_deactivate(adapter);
1372 return (0);
1373}
1374#endif
1375
1376static void
1377cxgb_init(void *arg)

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

1385
1386static void
1387cxgb_init_locked(struct port_info *p)
1388{
1389 struct ifnet *ifp;
1390 adapter_t *sc = p->adapter;
1391 int err;
1392
1393 mtx_assert(&p->lock, MA_OWNED);
1394 ifp = p->ifp;
1395
1396 ADAPTER_LOCK(p->adapter);
1397 if ((sc->open_device_map == 0) && ((err = cxgb_up(sc)) < 0)) {
1398 ADAPTER_UNLOCK(p->adapter);
1399 cxgb_stop_locked(p);
1400 return;
1401 }
1402 if (p->adapter->open_device_map == 0)
1403 t3_intr_clear(sc);
1404
1405 setbit(&p->adapter->open_device_map, p->port);
1406 ADAPTER_UNLOCK(p->adapter);
1407
1408 if (is_offload(sc) && !ofld_disable) {
1409 err = offload_open(p);
1410 if (err)
1411 log(LOG_WARNING,
1412 "Could not initialize offload capabilities\n");
1413 }
1414 cxgb_link_start(p);
1415 t3_link_changed(sc, p->port);
1416 ifp->if_baudrate = p->link_config.speed * 1000000;
1417
1418 t3_port_intr_enable(sc, p->port);
1419
1420 callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
1421 cxgb_tick, sc);
1422
1423 ifp->if_drv_flags |= IFF_DRV_RUNNING;
1424 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
1425}
1426
1427static void
1428cxgb_set_rxmode(struct port_info *p)
1429{
1430 struct t3_rx_mode rm;
1431 struct cmac *mac = &p->mac;
1432
1433 mtx_assert(&p->lock, MA_OWNED);
1434
1435 t3_init_rx_mode(&rm, p);
1436 t3_mac_set_rx_mode(mac, &rm);
1437}
1438
1439static void
1440cxgb_stop_locked(struct port_info *p)
1441{
1442 struct ifnet *ifp;
1443
1444 mtx_assert(&p->lock, MA_OWNED);
1445 mtx_assert(&p->adapter->lock, MA_NOTOWNED);
1446
1447 ifp = p->ifp;
1448
1449 t3_port_intr_disable(p->adapter, p->port);
1450 ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
1451 p->phy.ops->power_down(&p->phy, 1);
1452 t3_mac_disable(&p->mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX);
1453
1454 ADAPTER_LOCK(p->adapter);
1455 clrbit(&p->adapter->open_device_map, p->port);
1456 /*
1457 * XXX cancel check_task
1458 */
1459 if (p->adapter->open_device_map == 0)
1460 cxgb_down(p->adapter);
1461 ADAPTER_UNLOCK(p->adapter);
1462}
1463
1464static int
1465cxgb_set_mtu(struct port_info *p, int mtu)
1466{
1467 struct ifnet *ifp = p->ifp;
1468 int error = 0;
1469

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

1506 if (!(ifp->if_drv_flags & IFF_DRV_RUNNING))
1507 cxgb_init_locked(p);
1508 arp_ifinit(ifp, ifa);
1509 } else
1510 error = ether_ioctl(ifp, command, data);
1511 PORT_UNLOCK(p);
1512 break;
1513 case SIOCSIFFLAGS:
1514 PORT_LOCK(p);
1515 if (ifp->if_flags & IFF_UP) {
1516 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1517 flags = p->if_flags;
1518 if (((ifp->if_flags ^ flags) & IFF_PROMISC) ||
1519 ((ifp->if_flags ^ flags) & IFF_ALLMULTI))
1520 cxgb_set_rxmode(p);
1521
1522 } else
1523 cxgb_init_locked(p);
1524 p->if_flags = ifp->if_flags;
1525 } else {
1526 callout_stop(&p->adapter->cxgb_tick_ch);
1527 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1528 cxgb_stop_locked(p);
1529 } else {
1530 adapter_t *sc = p->adapter;
1531 callout_reset(&sc->cxgb_tick_ch,
1532 sc->params.stats_update_period * hz,
1533 cxgb_tick, sc);
1534 }
1535 }
1536 PORT_UNLOCK(p);
1537 break;
1538 case SIOCSIFMEDIA:
1539 case SIOCGIFMEDIA:
1540 error = ifmedia_ioctl(ifp, ifr, &p->media, command);
1541 break;
1542 case SIOCSIFCAP:

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

1741
1742static void
1743cxgb_async_intr(void *data)
1744{
1745 adapter_t *sc = data;
1746
1747 if (cxgb_debug)
1748 device_printf(sc->dev, "cxgb_async_intr\n");
1749
1750 t3_slow_intr_handler(sc);
1751
1752}
1753
1754static void
1755cxgb_ext_intr_handler(void *arg, int count)
1756{
1757 adapter_t *sc = (adapter_t *)arg;
1758
1759 if (cxgb_debug)

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

1819 PORT_UNLOCK(p);
1820 }
1821}
1822
1823static void
1824cxgb_tick(void *arg)
1825{
1826 adapter_t *sc = (adapter_t *)arg;
1827 const struct adapter_params *p = &sc->params;
1828
1829 if (p->linkpoll_period)
1830 check_link_status(sc);
1831 callout_reset(&sc->cxgb_tick_ch, sc->params.stats_update_period * hz,
1832 cxgb_tick, sc);
1833
1834 /*
1835 * adapter lock can currently only be acquire after the
1836 * port lock
1837 */
1838 ADAPTER_UNLOCK(sc);
1839
1840 if (p->rev == T3_REV_B2)

--- 466 unchanged lines hidden ---