summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornp <np@FreeBSD.org>2015-06-06 18:00:36 +0000
committernp <np@FreeBSD.org>2015-06-06 18:00:36 +0000
commitedfdc5c75d4637e168dba5b0cfdbf09e7fd0f150 (patch)
tree61b344d86b4d21ff87e46013e425432b39918067
parentfcae6374c46e27235434ab48a7b1cd1da69782dd (diff)
downloadFreeBSD-src-edfdc5c75d4637e168dba5b0cfdbf09e7fd0f150.zip
FreeBSD-src-edfdc5c75d4637e168dba5b0cfdbf09e7fd0f150.tar.gz
MFC r278239 and r278374.
r278239: cxgbe(4): reserve id for iSCSI upper layer driver. r278374: cxgbe(4): tidy up some of the interaction between the Upper Layer Drivers (ULDs) and the base if_cxgbe driver. Track the per-adapter activation of ULDs in a new "active_ulds" field. This was done pretty arbitrarily before this change -- via TOM_INIT_DONE in adapter->flags for TOM, and the (1 << MAX_NPORTS) bit in adapter->offload_map for iWARP. iWARP and hw-accelerated iSCSI rely on the TOE (supported by the TOM ULD). The rules are: a) If the iWARP and/or iSCSI ULDs are available when TOE is enabled then iWARP and/or iSCSI are enabled too. b) When the iWARP and iSCSI modules are loaded they go looking for adapters with TOE enabled and enable themselves on that adapter. c) You cannot deactivate or unload the TOM module from underneath iWARP or iSCSI. Any such attempt will fail with EBUSY.
-rw-r--r--sys/dev/cxgbe/adapter.h5
-rw-r--r--sys/dev/cxgbe/iw_cxgbe/device.c13
-rw-r--r--sys/dev/cxgbe/offload.h7
-rw-r--r--sys/dev/cxgbe/t4_main.c53
-rw-r--r--sys/dev/cxgbe/tom/t4_listen.c2
-rw-r--r--sys/dev/cxgbe/tom/t4_tom.c9
6 files changed, 60 insertions, 29 deletions
diff --git a/sys/dev/cxgbe/adapter.h b/sys/dev/cxgbe/adapter.h
index df15fcc..656f6d2 100644
--- a/sys/dev/cxgbe/adapter.h
+++ b/sys/dev/cxgbe/adapter.h
@@ -186,7 +186,7 @@ enum {
/* INTR_DIRECT = (1 << 2), No longer used. */
MASTER_PF = (1 << 3),
ADAP_SYSCTL_CTX = (1 << 4),
- TOM_INIT_DONE = (1 << 5),
+ /* TOM_INIT_DONE= (1 << 5), No longer used */
BUF_PACKING_OK = (1 << 6),
CXGBE_BUSY = (1 << 9),
@@ -751,7 +751,8 @@ struct adapter {
uint16_t doorbells;
int open_device_map;
#ifdef TCP_OFFLOAD
- int offload_map;
+ int offload_map; /* ports with IFCAP_TOE enabled */
+ int active_ulds; /* ULDs activated on this adapter */
#endif
int flags;
diff --git a/sys/dev/cxgbe/iw_cxgbe/device.c b/sys/dev/cxgbe/iw_cxgbe/device.c
index adb283d..bb6ac9d 100644
--- a/sys/dev/cxgbe/iw_cxgbe/device.c
+++ b/sys/dev/cxgbe/iw_cxgbe/device.c
@@ -213,7 +213,7 @@ c4iw_activate(struct adapter *sc)
ASSERT_SYNCHRONIZED_OP(sc);
- if (isset(&sc->offload_map, MAX_NPORTS)) {
+ if (uld_active(sc, ULD_IWARP)) {
KASSERT(0, ("%s: RDMA already eanbled on sc %p", __func__, sc));
return (0);
}
@@ -265,9 +265,9 @@ c4iw_activate_all(struct adapter *sc, void *arg __unused)
if (begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4iwact") != 0)
return;
- if (!isset(&sc->offload_map, MAX_NPORTS) &&
- t4_activate_uld(sc, ULD_IWARP) == 0)
- setbit(&sc->offload_map, MAX_NPORTS);
+ /* Activate iWARP if any port on this adapter has IFCAP_TOE enabled. */
+ if (sc->offload_map && !uld_active(sc, ULD_IWARP))
+ (void) t4_activate_uld(sc, ULD_IWARP);
end_synchronized_op(sc, 0);
}
@@ -279,9 +279,8 @@ c4iw_deactivate_all(struct adapter *sc, void *arg __unused)
if (begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4iwdea") != 0)
return;
- if (isset(&sc->offload_map, MAX_NPORTS) &&
- t4_deactivate_uld(sc, ULD_IWARP) == 0)
- clrbit(&sc->offload_map, MAX_NPORTS);
+ if (uld_active(sc, ULD_IWARP))
+ (void) t4_deactivate_uld(sc, ULD_IWARP);
end_synchronized_op(sc, 0);
}
diff --git a/sys/dev/cxgbe/offload.h b/sys/dev/cxgbe/offload.h
index ea681fe..2a12283 100644
--- a/sys/dev/cxgbe/offload.h
+++ b/sys/dev/cxgbe/offload.h
@@ -127,8 +127,10 @@ struct t4_virt_res { /* virtualized HW resources */
#ifdef TCP_OFFLOAD
enum {
- ULD_TOM = 1,
- ULD_IWARP = 2,
+ ULD_TOM = 0,
+ ULD_IWARP,
+ ULD_ISCSI,
+ ULD_MAX = ULD_ISCSI
};
struct adapter;
@@ -155,5 +157,6 @@ int t4_unregister_uld(struct uld_info *);
int t4_activate_uld(struct adapter *, int);
int t4_deactivate_uld(struct adapter *, int);
void t4_iscsi_init(struct ifnet *, unsigned int, const unsigned int *);
+int uld_active(struct adapter *, int);
#endif
#endif
diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index eee3965..5d08737 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -7057,7 +7057,7 @@ set_filter_mode(struct adapter *sc, uint32_t mode)
}
#ifdef TCP_OFFLOAD
- if (sc->offload_map) {
+ if (uld_active(sc, ULD_TOM)) {
rc = EBUSY;
goto done;
}
@@ -8142,7 +8142,7 @@ toe_capability(struct port_info *pi, int enable)
if (isset(&sc->offload_map, pi->port_id))
return (0);
- if (!(sc->flags & TOM_INIT_DONE)) {
+ if (!uld_active(sc, ULD_TOM)) {
rc = t4_activate_uld(sc, ULD_TOM);
if (rc == EAGAIN) {
log(LOG_WARNING,
@@ -8153,16 +8153,22 @@ toe_capability(struct port_info *pi, int enable)
return (rc);
KASSERT(sc->tom_softc != NULL,
("%s: TOM activated but softc NULL", __func__));
- KASSERT(sc->flags & TOM_INIT_DONE,
+ KASSERT(uld_active(sc, ULD_TOM),
("%s: TOM activated but flag not set", __func__));
}
+ /* Activate iWARP and iSCSI too, if the modules are loaded. */
+ if (!uld_active(sc, ULD_IWARP))
+ (void) t4_activate_uld(sc, ULD_IWARP);
+ if (!uld_active(sc, ULD_ISCSI))
+ (void) t4_activate_uld(sc, ULD_ISCSI);
+
setbit(&sc->offload_map, pi->port_id);
} else {
if (!isset(&sc->offload_map, pi->port_id))
return (0);
- KASSERT(sc->flags & TOM_INIT_DONE,
+ KASSERT(uld_active(sc, ULD_TOM),
("%s: TOM never initialized?", __func__));
clrbit(&sc->offload_map, pi->port_id);
}
@@ -8222,11 +8228,15 @@ done:
int
t4_activate_uld(struct adapter *sc, int id)
{
- int rc = EAGAIN;
+ int rc;
struct uld_info *ui;
ASSERT_SYNCHRONIZED_OP(sc);
+ if (id < 0 || id > ULD_MAX)
+ return (EINVAL);
+ rc = EAGAIN; /* kldoad the module with this ULD and try again. */
+
sx_slock(&t4_uld_list_lock);
SLIST_FOREACH(ui, &t4_uld_list, link) {
@@ -8234,16 +8244,18 @@ t4_activate_uld(struct adapter *sc, int id)
if (!(sc->flags & FULL_INIT_DONE)) {
rc = adapter_full_init(sc);
if (rc != 0)
- goto done;
+ break;
}
rc = ui->activate(sc);
- if (rc == 0)
+ if (rc == 0) {
+ setbit(&sc->active_ulds, id);
ui->refcount++;
- goto done;
+ }
+ break;
}
}
-done:
+
sx_sunlock(&t4_uld_list_lock);
return (rc);
@@ -8252,26 +8264,41 @@ done:
int
t4_deactivate_uld(struct adapter *sc, int id)
{
- int rc = EINVAL;
+ int rc;
struct uld_info *ui;
ASSERT_SYNCHRONIZED_OP(sc);
+ if (id < 0 || id > ULD_MAX)
+ return (EINVAL);
+ rc = ENXIO;
+
sx_slock(&t4_uld_list_lock);
SLIST_FOREACH(ui, &t4_uld_list, link) {
if (ui->uld_id == id) {
rc = ui->deactivate(sc);
- if (rc == 0)
+ if (rc == 0) {
+ clrbit(&sc->active_ulds, id);
ui->refcount--;
- goto done;
+ }
+ break;
}
}
-done:
+
sx_sunlock(&t4_uld_list_lock);
return (rc);
}
+
+int
+uld_active(struct adapter *sc, int uld_id)
+{
+
+ MPASS(uld_id >= 0 && uld_id <= ULD_MAX);
+
+ return (isset(&sc->active_ulds, uld_id));
+}
#endif
/*
diff --git a/sys/dev/cxgbe/tom/t4_listen.c b/sys/dev/cxgbe/tom/t4_listen.c
index 1c25baf..9a71221 100644
--- a/sys/dev/cxgbe/tom/t4_listen.c
+++ b/sys/dev/cxgbe/tom/t4_listen.c
@@ -523,7 +523,7 @@ t4_listen_start(struct toedev *tod, struct tcpcb *tp)
goto done;
}
- KASSERT(sc->flags & TOM_INIT_DONE,
+ KASSERT(uld_active(sc, ULD_TOM),
("%s: TOM not initialized", __func__));
#endif
diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c
index 725e3e2..e21cdd5 100644
--- a/sys/dev/cxgbe/tom/t4_tom.c
+++ b/sys/dev/cxgbe/tom/t4_tom.c
@@ -745,7 +745,7 @@ update_clip(struct adapter *sc, void *arg __unused)
if (begin_synchronized_op(sc, NULL, HOLD_LOCK, "t4tomuc"))
return;
- if (sc->flags & TOM_INIT_DONE)
+ if (uld_active(sc, ULD_TOM))
update_clip_table(sc, sc->tom_softc);
end_synchronized_op(sc, LOCK_HELD);
@@ -1024,7 +1024,6 @@ t4_tom_activate(struct adapter *sc)
TOEDEV(sc->port[i]->ifp) = &td->tod;
sc->tom_softc = td;
- sc->flags |= TOM_INIT_DONE;
register_toedev(sc->tom_softc);
done:
@@ -1047,6 +1046,9 @@ t4_tom_deactivate(struct adapter *sc)
if (sc->offload_map != 0)
return (EBUSY); /* at least one port has IFCAP_TOE enabled */
+ if (uld_active(sc, ULD_IWARP) || uld_active(sc, ULD_ISCSI))
+ return (EBUSY); /* both iWARP and iSCSI rely on the TOE. */
+
mtx_lock(&td->toep_list_lock);
if (!TAILQ_EMPTY(&td->toep_list))
rc = EBUSY;
@@ -1067,7 +1069,6 @@ t4_tom_deactivate(struct adapter *sc)
unregister_toedev(sc->tom_softc);
free_tom_data(sc, td);
sc->tom_softc = NULL;
- sc->flags &= ~TOM_INIT_DONE;
}
return (rc);
@@ -1121,7 +1122,7 @@ tom_uninit(struct adapter *sc, void *arg __unused)
return;
/* Try to free resources (works only if no port has IFCAP_TOE) */
- if (sc->flags & TOM_INIT_DONE)
+ if (uld_active(sc, ULD_TOM))
t4_deactivate_uld(sc, ULD_TOM);
end_synchronized_op(sc, 0);
OpenPOWER on IntegriCloud