aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/cxgb/cxgb_main.c
diff options
context:
space:
mode:
authorNavdeep Parhar <np@FreeBSD.org>2009-10-05 20:21:41 +0000
committerNavdeep Parhar <np@FreeBSD.org>2009-10-05 20:21:41 +0000
commitc01f2b830100064370fe9b0fe63f8d822967c755 (patch)
tree802f7eebcdd7790a4ecc31d402dcf0fa269b0ff2 /sys/dev/cxgb/cxgb_main.c
parent2880192bf207cdbe7d7a415f1c6a4818281a0569 (diff)
downloadsrc-c01f2b830100064370fe9b0fe63f8d822967c755.tar.gz
src-c01f2b830100064370fe9b0fe63f8d822967c755.zip
cxgb(4) updates, including:
- support for the new Gen-2, BT, and LP-CR cards. - T3 firmware 7.7.0 - shared "common code" updates. Approved by: gnn (mentor) Obtained from: Chelsio MFC after: 1 month
Notes
Notes: svn path=/head/; revision=197791
Diffstat (limited to 'sys/dev/cxgb/cxgb_main.c')
-rw-r--r--sys/dev/cxgb/cxgb_main.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c
index 596609b89d95..26d4b508c0aa 100644
--- a/sys/dev/cxgb/cxgb_main.c
+++ b/sys/dev/cxgb/cxgb_main.c
@@ -116,7 +116,7 @@ static int cxgb_get_regs_len(void);
static int offload_open(struct port_info *pi);
static void touch_bars(device_t dev);
static int offload_close(struct t3cdev *tdev);
-int t3_detect_link_fault(adapter_t *adapter, int port_id);
+static void cxgb_update_mac_settings(struct port_info *p);
static device_method_t cxgb_controller_methods[] = {
DEVMETHOD(device_probe, cxgb_controller_probe),
@@ -291,7 +291,9 @@ struct cxgb_ident {
{PCI_VENDOR_ID_CHELSIO, 0x0031, 3, "T3B20"},
{PCI_VENDOR_ID_CHELSIO, 0x0032, 1, "T3B02"},
{PCI_VENDOR_ID_CHELSIO, 0x0033, 4, "T3B04"},
- {PCI_VENDOR_ID_CHELSIO, 0x0035, 6, "N310E"},
+ {PCI_VENDOR_ID_CHELSIO, 0x0035, 6, "T3C10"},
+ {PCI_VENDOR_ID_CHELSIO, 0x0036, 3, "S320E-CR"},
+ {PCI_VENDOR_ID_CHELSIO, 0x0037, 7, "N320E-G2"},
{0, 0, 0, NULL}
};
@@ -508,6 +510,9 @@ cxgb_controller_attach(device_t dev)
sc->bh = rman_get_bushandle(sc->regs_res);
sc->mmio_len = rman_get_size(sc->regs_res);
+ for (i = 0; i < MAX_NPORTS; i++)
+ sc->port[i].adapter = sc;
+
if (t3_prep_adapter(sc, ai, 1) < 0) {
printf("prep adapter failed\n");
error = ENODEV;
@@ -1222,8 +1227,8 @@ t3_os_pci_restore_state(struct adapter *sc)
/**
* t3_os_link_changed - handle link status changes
- * @adapter: the adapter associated with the link change
- * @port_id: the port index whose limk status has changed
+ * @sc: the adapter associated with the link change
+ * @port_id: the port index whose link status has changed
* @link_status: the new status of the link
* @speed: the new speed setting
* @duplex: the new duplex setting
@@ -1235,7 +1240,7 @@ t3_os_pci_restore_state(struct adapter *sc)
*/
void
t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed,
- int duplex, int fc)
+ int duplex, int fc, int mac_was_reset)
{
struct port_info *pi = &adapter->port[port_id];
struct ifnet *ifp = pi->ifp;
@@ -1243,6 +1248,13 @@ t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed,
/* no race with detach, so ifp should always be good */
KASSERT(ifp, ("%s: if detached.", __func__));
+ /* Reapply mac settings if they were lost due to a reset */
+ if (mac_was_reset) {
+ PORT_LOCK(pi);
+ cxgb_update_mac_settings(pi);
+ PORT_UNLOCK(pi);
+ }
+
if (link_status) {
ifp->if_baudrate = IF_Mbps(speed);
if_link_state_change(ifp, LINK_STATE_UP);
@@ -1917,7 +1929,7 @@ cxgb_init_synchronized(struct port_info *p)
PORT_LOCK(p);
t3_port_intr_enable(sc, p->port_id);
if (!mac->multiport)
- t3_mac_reset(mac);
+ t3_mac_init(mac);
cxgb_update_mac_settings(p);
t3_link_start(&p->phy, mac, &p->link_config);
t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX);
@@ -1992,7 +2004,7 @@ cxgb_uninit_synchronized(struct port_info *pi)
PORT_UNLOCK(pi);
pi->link_config.link_ok = 0;
- t3_os_link_changed(sc, pi->port_id, 0, 0, 0, 0);
+ t3_os_link_changed(sc, pi->port_id, 0, 0, 0, 0, 0);
if ((sc->open_device_map & PORT_MASK) == 0)
offload_close(&sc->tdev);
@@ -2335,6 +2347,19 @@ cxgb_ext_intr_handler(void *arg, int count)
ADAPTER_UNLOCK(sc);
}
+static inline int
+link_poll_needed(struct port_info *p)
+{
+ struct cphy *phy = &p->phy;
+
+ if (phy->caps & POLL_LINK_1ST_TIME) {
+ p->phy.caps &= ~POLL_LINK_1ST_TIME;
+ return (1);
+ }
+
+ return (p->link_fault || !(phy->caps & SUPPORTED_LINK_IRQ));
+}
+
static void
check_link_status(adapter_t *sc)
{
@@ -2346,7 +2371,7 @@ check_link_status(adapter_t *sc)
if (!isset(&sc->open_device_map, p->port_id))
continue;
- if (p->link_fault || !(p->phy.caps & SUPPORTED_IRQ))
+ if (link_poll_needed(p))
t3_link_changed(sc, i);
}
}
@@ -2366,7 +2391,8 @@ check_t3b2_mac(struct adapter *sc)
struct ifnet *ifp = p->ifp;
#endif
- if (!isset(&sc->open_device_map, p->port_id))
+ if (!isset(&sc->open_device_map, p->port_id) || p->link_fault ||
+ !p->link_config.link_ok)
continue;
KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING,
@@ -2414,7 +2440,6 @@ cxgb_tick_handler(void *arg, int count)
return;
check_link_status(sc);
- sc->check_task_cnt++;
if (p->rev == T3_REV_B2 && p->nports < 4 && sc->open_device_map)
check_t3b2_mac(sc);