Deleted Added
full compact
t4_main.c (244580) t4_main.c (245274)
1/*-
2 * Copyright (c) 2011 Chelsio Communications, Inc.
3 * All rights reserved.
4 * Written by: Navdeep Parhar <np@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2011 Chelsio Communications, Inc.
3 * All rights reserved.
4 * Written by: Navdeep Parhar <np@FreeBSD.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include <sys/cdefs.h>
29__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_main.c 244580 2012-12-22 07:47:07Z np $");
29__FBSDID("$FreeBSD: head/sys/dev/cxgbe/t4_main.c 245274 2013-01-10 23:56:50Z np $");
30
31#include "opt_inet.h"
32#include "opt_inet6.h"
33
34#include <sys/param.h>
35#include <sys/conf.h>
36#include <sys/priv.h>
37#include <sys/kernel.h>

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

279static int upload_config_file(struct adapter *, const struct firmware *,
280 uint32_t *, uint32_t *);
281static int partition_resources(struct adapter *, const struct firmware *);
282static int get_params__pre_init(struct adapter *);
283static int get_params__post_init(struct adapter *);
284static void t4_set_desc(struct adapter *);
285static void build_medialist(struct port_info *);
286static int update_mac_settings(struct port_info *, int);
30
31#include "opt_inet.h"
32#include "opt_inet6.h"
33
34#include <sys/param.h>
35#include <sys/conf.h>
36#include <sys/priv.h>
37#include <sys/kernel.h>

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

279static int upload_config_file(struct adapter *, const struct firmware *,
280 uint32_t *, uint32_t *);
281static int partition_resources(struct adapter *, const struct firmware *);
282static int get_params__pre_init(struct adapter *);
283static int get_params__post_init(struct adapter *);
284static void t4_set_desc(struct adapter *);
285static void build_medialist(struct port_info *);
286static int update_mac_settings(struct port_info *, int);
287static int cxgbe_init_locked(struct port_info *);
288static int cxgbe_init_synchronized(struct port_info *);
287static int cxgbe_init_synchronized(struct port_info *);
289static int cxgbe_uninit_locked(struct port_info *);
290static int cxgbe_uninit_synchronized(struct port_info *);
291static int setup_intr_handlers(struct adapter *);
292static int adapter_full_init(struct adapter *);
293static int adapter_full_uninit(struct adapter *);
294static int port_full_init(struct port_info *);
295static int port_full_uninit(struct port_info *);
296static void quiesce_eq(struct adapter *, struct sge_eq *);
297static void quiesce_iq(struct adapter *, struct sge_iq *);

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

343static inline uint64_t get_filter_hits(struct adapter *, uint32_t);
344static int get_filter(struct adapter *, struct t4_filter *);
345static int set_filter(struct adapter *, struct t4_filter *);
346static int del_filter(struct adapter *, struct t4_filter *);
347static void clear_filter(struct filter_entry *);
348static int set_filter_wr(struct adapter *, int);
349static int del_filter_wr(struct adapter *, int);
350static int get_sge_context(struct adapter *, struct t4_sge_context *);
288static int cxgbe_uninit_synchronized(struct port_info *);
289static int setup_intr_handlers(struct adapter *);
290static int adapter_full_init(struct adapter *);
291static int adapter_full_uninit(struct adapter *);
292static int port_full_init(struct port_info *);
293static int port_full_uninit(struct port_info *);
294static void quiesce_eq(struct adapter *, struct sge_eq *);
295static void quiesce_iq(struct adapter *, struct sge_iq *);

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

341static inline uint64_t get_filter_hits(struct adapter *, uint32_t);
342static int get_filter(struct adapter *, struct t4_filter *);
343static int set_filter(struct adapter *, struct t4_filter *);
344static int del_filter(struct adapter *, struct t4_filter *);
345static void clear_filter(struct filter_entry *);
346static int set_filter_wr(struct adapter *, int);
347static int del_filter_wr(struct adapter *, int);
348static int get_sge_context(struct adapter *, struct t4_sge_context *);
349static int load_fw(struct adapter *, struct t4_data *);
351static int read_card_mem(struct adapter *, struct t4_mem_range *);
352static int read_i2c(struct adapter *, struct t4_i2c_data *);
353#ifdef TCP_OFFLOAD
354static int toe_capability(struct port_info *, int);
355#endif
356static int t4_mod_event(module_t, int, void *);
357
358struct t4_pciids {

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

815 t4_destroy_dma_tag(sc);
816 if (mtx_initialized(&sc->sc_lock)) {
817 mtx_lock(&t4_list_lock);
818 SLIST_REMOVE(&t4_list, sc, adapter, link);
819 mtx_unlock(&t4_list_lock);
820 mtx_destroy(&sc->sc_lock);
821 }
822
350static int read_card_mem(struct adapter *, struct t4_mem_range *);
351static int read_i2c(struct adapter *, struct t4_i2c_data *);
352#ifdef TCP_OFFLOAD
353static int toe_capability(struct port_info *, int);
354#endif
355static int t4_mod_event(module_t, int, void *);
356
357struct t4_pciids {

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

814 t4_destroy_dma_tag(sc);
815 if (mtx_initialized(&sc->sc_lock)) {
816 mtx_lock(&t4_list_lock);
817 SLIST_REMOVE(&t4_list, sc, adapter, link);
818 mtx_unlock(&t4_list_lock);
819 mtx_destroy(&sc->sc_lock);
820 }
821
822 if (mtx_initialized(&sc->tids.ftid_lock))
823 mtx_destroy(&sc->tids.ftid_lock);
823 if (mtx_initialized(&sc->sfl_lock))
824 mtx_destroy(&sc->sfl_lock);
825
826 bzero(sc, sizeof(*sc));
827
828 return (0);
829}
830

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

913
914 /* Tell if_ioctl and if_init that the port is going away */
915 ADAPTER_LOCK(sc);
916 SET_DOOMED(pi);
917 wakeup(&sc->flags);
918 while (IS_BUSY(sc))
919 mtx_sleep(&sc->flags, &sc->sc_lock, 0, "t4detach", 0);
920 SET_BUSY(sc);
824 if (mtx_initialized(&sc->sfl_lock))
825 mtx_destroy(&sc->sfl_lock);
826
827 bzero(sc, sizeof(*sc));
828
829 return (0);
830}
831

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

914
915 /* Tell if_ioctl and if_init that the port is going away */
916 ADAPTER_LOCK(sc);
917 SET_DOOMED(pi);
918 wakeup(&sc->flags);
919 while (IS_BUSY(sc))
920 mtx_sleep(&sc->flags, &sc->sc_lock, 0, "t4detach", 0);
921 SET_BUSY(sc);
922#ifdef INVARIANTS
923 sc->last_op = "t4detach";
924 sc->last_op_thr = curthread;
925#endif
921 ADAPTER_UNLOCK(sc);
922
923 if (pi->vlan_c)
924 EVENTHANDLER_DEREGISTER(vlan_config, pi->vlan_c);
925
926 PORT_LOCK(pi);
927 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
928 callout_stop(&pi->tick);

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

934 port_full_uninit(pi);
935
936 ifmedia_removeall(&pi->media);
937 ether_ifdetach(pi->ifp);
938 if_free(pi->ifp);
939
940 ADAPTER_LOCK(sc);
941 CLR_BUSY(sc);
926 ADAPTER_UNLOCK(sc);
927
928 if (pi->vlan_c)
929 EVENTHANDLER_DEREGISTER(vlan_config, pi->vlan_c);
930
931 PORT_LOCK(pi);
932 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
933 callout_stop(&pi->tick);

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

939 port_full_uninit(pi);
940
941 ifmedia_removeall(&pi->media);
942 ether_ifdetach(pi->ifp);
943 if_free(pi->ifp);
944
945 ADAPTER_LOCK(sc);
946 CLR_BUSY(sc);
942 wakeup_one(&sc->flags);
947 wakeup(&sc->flags);
943 ADAPTER_UNLOCK(sc);
944
945 return (0);
946}
947
948static void
949cxgbe_init(void *arg)
950{
951 struct port_info *pi = arg;
952 struct adapter *sc = pi->adapter;
953
948 ADAPTER_UNLOCK(sc);
949
950 return (0);
951}
952
953static void
954cxgbe_init(void *arg)
955{
956 struct port_info *pi = arg;
957 struct adapter *sc = pi->adapter;
958
954 ADAPTER_LOCK(sc);
955 cxgbe_init_locked(pi); /* releases adapter lock */
956 ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
959 if (begin_synchronized_op(sc, pi, SLEEP_OK | INTR_OK, "t4init") != 0)
960 return;
961 cxgbe_init_synchronized(pi);
962 end_synchronized_op(sc, 0);
957}
958
959static int
960cxgbe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
961{
962 int rc = 0, mtu, flags;
963 struct port_info *pi = ifp->if_softc;
964 struct adapter *sc = pi->adapter;
965 struct ifreq *ifr = (struct ifreq *)data;
966 uint32_t mask;
967
968 switch (cmd) {
969 case SIOCSIFMTU:
963}
964
965static int
966cxgbe_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
967{
968 int rc = 0, mtu, flags;
969 struct port_info *pi = ifp->if_softc;
970 struct adapter *sc = pi->adapter;
971 struct ifreq *ifr = (struct ifreq *)data;
972 uint32_t mask;
973
974 switch (cmd) {
975 case SIOCSIFMTU:
970 ADAPTER_LOCK(sc);
971 rc = IS_DOOMED(pi) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
972 if (rc) {
973fail:
974 ADAPTER_UNLOCK(sc);
976 mtu = ifr->ifr_mtu;
977 if ((mtu < ETHERMIN) || (mtu > ETHERMTU_JUMBO))
978 return (EINVAL);
979
980 rc = begin_synchronized_op(sc, pi, SLEEP_OK | INTR_OK, "t4mtu");
981 if (rc)
975 return (rc);
982 return (rc);
983 ifp->if_mtu = mtu;
984 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
985 t4_update_fl_bufsize(ifp);
986 rc = update_mac_settings(pi, XGMAC_MTU);
976 }
987 }
977
978 mtu = ifr->ifr_mtu;
979 if ((mtu < ETHERMIN) || (mtu > ETHERMTU_JUMBO)) {
980 rc = EINVAL;
981 } else {
982 ifp->if_mtu = mtu;
983 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
984 t4_update_fl_bufsize(ifp);
985 PORT_LOCK(pi);
986 rc = update_mac_settings(pi, XGMAC_MTU);
987 PORT_UNLOCK(pi);
988 }
989 }
990 ADAPTER_UNLOCK(sc);
988 end_synchronized_op(sc, 0);
991 break;
992
993 case SIOCSIFFLAGS:
989 break;
990
991 case SIOCSIFFLAGS:
994 ADAPTER_LOCK(sc);
995 if (IS_DOOMED(pi)) {
996 rc = ENXIO;
997 goto fail;
998 }
992 rc = begin_synchronized_op(sc, pi, SLEEP_OK | INTR_OK, "t4flg");
993 if (rc)
994 return (rc);
995
999 if (ifp->if_flags & IFF_UP) {
1000 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1001 flags = pi->if_flags;
1002 if ((ifp->if_flags ^ flags) &
1003 (IFF_PROMISC | IFF_ALLMULTI)) {
996 if (ifp->if_flags & IFF_UP) {
997 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
998 flags = pi->if_flags;
999 if ((ifp->if_flags ^ flags) &
1000 (IFF_PROMISC | IFF_ALLMULTI)) {
1004 if (IS_BUSY(sc)) {
1005 rc = EBUSY;
1006 goto fail;
1007 }
1008 PORT_LOCK(pi);
1009 rc = update_mac_settings(pi,
1010 XGMAC_PROMISC | XGMAC_ALLMULTI);
1001 rc = update_mac_settings(pi,
1002 XGMAC_PROMISC | XGMAC_ALLMULTI);
1011 PORT_UNLOCK(pi);
1012 }
1003 }
1013 ADAPTER_UNLOCK(sc);
1014 } else
1004 } else
1015 rc = cxgbe_init_locked(pi);
1005 rc = cxgbe_init_synchronized(pi);
1016 pi->if_flags = ifp->if_flags;
1017 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1006 pi->if_flags = ifp->if_flags;
1007 } else if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1018 rc = cxgbe_uninit_locked(pi);
1019 else
1020 ADAPTER_UNLOCK(sc);
1021
1022 ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
1008 rc = cxgbe_uninit_synchronized(pi);
1009 end_synchronized_op(sc, 0);
1023 break;
1024
1025 case SIOCADDMULTI:
1010 break;
1011
1012 case SIOCADDMULTI:
1026 case SIOCDELMULTI: /* these two can be called with a mutex held :-( */
1027 ADAPTER_LOCK(sc);
1028 rc = IS_DOOMED(pi) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
1013 case SIOCDELMULTI: /* these two are called with a mutex held :-( */
1014 rc = begin_synchronized_op(sc, pi, HOLD_LOCK, "t4multi");
1029 if (rc)
1015 if (rc)
1030 goto fail;
1031
1032 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1033 PORT_LOCK(pi);
1016 return (rc);
1017 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1034 rc = update_mac_settings(pi, XGMAC_MCADDRS);
1018 rc = update_mac_settings(pi, XGMAC_MCADDRS);
1035 PORT_UNLOCK(pi);
1036 }
1037 ADAPTER_UNLOCK(sc);
1019 end_synchronized_op(sc, LOCK_HELD);
1038 break;
1039
1040 case SIOCSIFCAP:
1020 break;
1021
1022 case SIOCSIFCAP:
1041 ADAPTER_LOCK(sc);
1042 rc = IS_DOOMED(pi) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
1023 rc = begin_synchronized_op(sc, pi, SLEEP_OK | INTR_OK, "t4cap");
1043 if (rc)
1024 if (rc)
1044 goto fail;
1025 return (rc);
1045
1046 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
1047 if (mask & IFCAP_TXCSUM) {
1048 ifp->if_capenable ^= IFCAP_TXCSUM;
1049 ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
1050
1051 if (IFCAP_TSO4 & ifp->if_capenable &&
1052 !(IFCAP_TXCSUM & ifp->if_capenable)) {

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

1117 if (rc != 0)
1118 goto fail;
1119
1120 ifp->if_capenable ^= mask;
1121 }
1122#endif
1123 if (mask & IFCAP_VLAN_HWTAGGING) {
1124 ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
1026
1027 mask = ifr->ifr_reqcap ^ ifp->if_capenable;
1028 if (mask & IFCAP_TXCSUM) {
1029 ifp->if_capenable ^= IFCAP_TXCSUM;
1030 ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
1031
1032 if (IFCAP_TSO4 & ifp->if_capenable &&
1033 !(IFCAP_TXCSUM & ifp->if_capenable)) {

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

1098 if (rc != 0)
1099 goto fail;
1100
1101 ifp->if_capenable ^= mask;
1102 }
1103#endif
1104 if (mask & IFCAP_VLAN_HWTAGGING) {
1105 ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
1125 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
1126 PORT_LOCK(pi);
1106 if (ifp->if_drv_flags & IFF_DRV_RUNNING)
1127 rc = update_mac_settings(pi, XGMAC_VLANEX);
1107 rc = update_mac_settings(pi, XGMAC_VLANEX);
1128 PORT_UNLOCK(pi);
1129 }
1130 }
1131 if (mask & IFCAP_VLAN_MTU) {
1132 ifp->if_capenable ^= IFCAP_VLAN_MTU;
1133
1134 /* Need to find out how to disable auto-mtu-inflation */
1135 }
1136 if (mask & IFCAP_VLAN_HWTSO)
1137 ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
1138 if (mask & IFCAP_VLAN_HWCSUM)
1139 ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
1140
1141#ifdef VLAN_CAPABILITIES
1142 VLAN_CAPABILITIES(ifp);
1143#endif
1108 }
1109 if (mask & IFCAP_VLAN_MTU) {
1110 ifp->if_capenable ^= IFCAP_VLAN_MTU;
1111
1112 /* Need to find out how to disable auto-mtu-inflation */
1113 }
1114 if (mask & IFCAP_VLAN_HWTSO)
1115 ifp->if_capenable ^= IFCAP_VLAN_HWTSO;
1116 if (mask & IFCAP_VLAN_HWCSUM)
1117 ifp->if_capenable ^= IFCAP_VLAN_HWCSUM;
1118
1119#ifdef VLAN_CAPABILITIES
1120 VLAN_CAPABILITIES(ifp);
1121#endif
1144 ADAPTER_UNLOCK(sc);
1122fail:
1123 end_synchronized_op(sc, 0);
1145 break;
1146
1147 case SIOCSIFMEDIA:
1148 case SIOCGIFMEDIA:
1149 ifmedia_ioctl(ifp, ifr, &pi->media, cmd);
1150 break;
1151
1152 default:

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

2106static int
2107update_mac_settings(struct port_info *pi, int flags)
2108{
2109 int rc;
2110 struct ifnet *ifp = pi->ifp;
2111 struct adapter *sc = pi->adapter;
2112 int mtu = -1, promisc = -1, allmulti = -1, vlanex = -1;
2113
1124 break;
1125
1126 case SIOCSIFMEDIA:
1127 case SIOCGIFMEDIA:
1128 ifmedia_ioctl(ifp, ifr, &pi->media, cmd);
1129 break;
1130
1131 default:

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

2085static int
2086update_mac_settings(struct port_info *pi, int flags)
2087{
2088 int rc;
2089 struct ifnet *ifp = pi->ifp;
2090 struct adapter *sc = pi->adapter;
2091 int mtu = -1, promisc = -1, allmulti = -1, vlanex = -1;
2092
2114 PORT_LOCK_ASSERT_OWNED(pi);
2093 ASSERT_SYNCHRONIZED_OP(sc);
2115 KASSERT(flags, ("%s: not told what to update.", __func__));
2116
2117 if (flags & XGMAC_MTU)
2118 mtu = ifp->if_mtu;
2119
2120 if (flags & XGMAC_PROMISC)
2121 promisc = ifp->if_flags & IFF_PROMISC ? 1 : 0;
2122

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

2208 if_printf(ifp, "failed to set mc address hash: %d", rc);
2209mcfail:
2210 if_maddr_runlock(ifp);
2211 }
2212
2213 return (rc);
2214}
2215
2094 KASSERT(flags, ("%s: not told what to update.", __func__));
2095
2096 if (flags & XGMAC_MTU)
2097 mtu = ifp->if_mtu;
2098
2099 if (flags & XGMAC_PROMISC)
2100 promisc = ifp->if_flags & IFF_PROMISC ? 1 : 0;
2101

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

2187 if_printf(ifp, "failed to set mc address hash: %d", rc);
2188mcfail:
2189 if_maddr_runlock(ifp);
2190 }
2191
2192 return (rc);
2193}
2194
2216static int
2217cxgbe_init_locked(struct port_info *pi)
2195int
2196begin_synchronized_op(struct adapter *sc, struct port_info *pi, int flags,
2197 char *wmesg)
2218{
2198{
2219 struct adapter *sc = pi->adapter;
2220 int rc = 0;
2199 int rc, pri;
2221
2200
2222 ADAPTER_LOCK_ASSERT_OWNED(sc);
2201#ifdef WITNESS
2202 /* the caller thinks it's ok to sleep, but is it really? */
2203 if (flags & SLEEP_OK)
2204 pause("t4slptst", 1);
2205#endif
2223
2206
2224 while (!IS_DOOMED(pi) && IS_BUSY(sc)) {
2225 if (mtx_sleep(&sc->flags, &sc->sc_lock, PCATCH, "t4init", 0)) {
2207 if (INTR_OK)
2208 pri = PCATCH;
2209 else
2210 pri = 0;
2211
2212 ADAPTER_LOCK(sc);
2213 for (;;) {
2214
2215 if (pi && IS_DOOMED(pi)) {
2216 rc = ENXIO;
2217 goto done;
2218 }
2219
2220 if (!IS_BUSY(sc)) {
2221 rc = 0;
2222 break;
2223 }
2224
2225 if (!(flags & SLEEP_OK)) {
2226 rc = EBUSY;
2227 goto done;
2228 }
2229
2230 if (mtx_sleep(&sc->flags, &sc->sc_lock, pri, wmesg, 0)) {
2226 rc = EINTR;
2227 goto done;
2228 }
2229 }
2231 rc = EINTR;
2232 goto done;
2233 }
2234 }
2230 if (IS_DOOMED(pi)) {
2231 rc = ENXIO;
2232 goto done;
2233 }
2234 KASSERT(!IS_BUSY(sc), ("%s: controller busy.", __func__));
2235
2235
2236 /* Give up the adapter lock, port init code can sleep. */
2236 KASSERT(!IS_BUSY(sc), ("%s: controller busy.", __func__));
2237 SET_BUSY(sc);
2237 SET_BUSY(sc);
2238 ADAPTER_UNLOCK(sc);
2238#ifdef INVARIANTS
2239 sc->last_op = wmesg;
2240 sc->last_op_thr = curthread;
2241#endif
2239
2242
2240 rc = cxgbe_init_synchronized(pi);
2241
2242done:
2243done:
2243 ADAPTER_LOCK(sc);
2244 if (!(flags & HOLD_LOCK) || rc)
2245 ADAPTER_UNLOCK(sc);
2246
2247 return (rc);
2248}
2249
2250void
2251end_synchronized_op(struct adapter *sc, int flags)
2252{
2253
2254 if (flags & LOCK_HELD)
2255 ADAPTER_LOCK_ASSERT_OWNED(sc);
2256 else
2257 ADAPTER_LOCK(sc);
2258
2244 KASSERT(IS_BUSY(sc), ("%s: controller not busy.", __func__));
2245 CLR_BUSY(sc);
2259 KASSERT(IS_BUSY(sc), ("%s: controller not busy.", __func__));
2260 CLR_BUSY(sc);
2246 wakeup_one(&sc->flags);
2261 wakeup(&sc->flags);
2247 ADAPTER_UNLOCK(sc);
2262 ADAPTER_UNLOCK(sc);
2248 return (rc);
2249}
2250
2251static int
2252cxgbe_init_synchronized(struct port_info *pi)
2253{
2254 struct adapter *sc = pi->adapter;
2255 struct ifnet *ifp = pi->ifp;
2256 int rc = 0;
2257
2263}
2264
2265static int
2266cxgbe_init_synchronized(struct port_info *pi)
2267{
2268 struct adapter *sc = pi->adapter;
2269 struct ifnet *ifp = pi->ifp;
2270 int rc = 0;
2271
2258 ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
2272 ASSERT_SYNCHRONIZED_OP(sc);
2259
2260 if (isset(&sc->open_device_map, pi->port_id)) {
2261 KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING,
2262 ("mismatch between open_device_map and if_drv_flags"));
2263 return (0); /* already running */
2264 }
2265
2266 if (!(sc->flags & FULL_INIT_DONE) &&
2267 ((rc = adapter_full_init(sc)) != 0))
2268 return (rc); /* error message displayed already */
2269
2270 if (!(pi->flags & PORT_INIT_DONE) &&
2271 ((rc = port_full_init(pi)) != 0))
2272 return (rc); /* error message displayed already */
2273
2273
2274 if (isset(&sc->open_device_map, pi->port_id)) {
2275 KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING,
2276 ("mismatch between open_device_map and if_drv_flags"));
2277 return (0); /* already running */
2278 }
2279
2280 if (!(sc->flags & FULL_INIT_DONE) &&
2281 ((rc = adapter_full_init(sc)) != 0))
2282 return (rc); /* error message displayed already */
2283
2284 if (!(pi->flags & PORT_INIT_DONE) &&
2285 ((rc = port_full_init(pi)) != 0))
2286 return (rc); /* error message displayed already */
2287
2274 PORT_LOCK(pi);
2275 rc = update_mac_settings(pi, XGMAC_ALL);
2288 rc = update_mac_settings(pi, XGMAC_ALL);
2276 PORT_UNLOCK(pi);
2277 if (rc)
2278 goto done; /* error message displayed already */
2279
2280 rc = -t4_link_start(sc, sc->mbox, pi->tx_chan, &pi->link_cfg);
2281 if (rc != 0) {
2282 if_printf(ifp, "start_link failed: %d\n", rc);
2283 goto done;
2284 }
2285
2286 rc = -t4_enable_vi(sc, sc->mbox, pi->viid, true, true);
2287 if (rc != 0) {
2288 if_printf(ifp, "enable_vi failed: %d\n", rc);
2289 goto done;
2290 }
2291
2292 /* all ok */
2293 setbit(&sc->open_device_map, pi->port_id);
2289 if (rc)
2290 goto done; /* error message displayed already */
2291
2292 rc = -t4_link_start(sc, sc->mbox, pi->tx_chan, &pi->link_cfg);
2293 if (rc != 0) {
2294 if_printf(ifp, "start_link failed: %d\n", rc);
2295 goto done;
2296 }
2297
2298 rc = -t4_enable_vi(sc, sc->mbox, pi->viid, true, true);
2299 if (rc != 0) {
2300 if_printf(ifp, "enable_vi failed: %d\n", rc);
2301 goto done;
2302 }
2303
2304 /* all ok */
2305 setbit(&sc->open_device_map, pi->port_id);
2306 PORT_LOCK(pi);
2294 ifp->if_drv_flags |= IFF_DRV_RUNNING;
2307 ifp->if_drv_flags |= IFF_DRV_RUNNING;
2308 PORT_UNLOCK(pi);
2295
2296 callout_reset(&pi->tick, hz, cxgbe_tick, pi);
2297done:
2298 if (rc != 0)
2299 cxgbe_uninit_synchronized(pi);
2300
2301 return (rc);
2302}
2303
2309
2310 callout_reset(&pi->tick, hz, cxgbe_tick, pi);
2311done:
2312 if (rc != 0)
2313 cxgbe_uninit_synchronized(pi);
2314
2315 return (rc);
2316}
2317
2304static int
2305cxgbe_uninit_locked(struct port_info *pi)
2306{
2307 struct adapter *sc = pi->adapter;
2308 int rc;
2309
2310 ADAPTER_LOCK_ASSERT_OWNED(sc);
2311
2312 while (!IS_DOOMED(pi) && IS_BUSY(sc)) {
2313 if (mtx_sleep(&sc->flags, &sc->sc_lock, PCATCH, "t4uninit", 0)) {
2314 rc = EINTR;
2315 goto done;
2316 }
2317 }
2318 if (IS_DOOMED(pi)) {
2319 rc = ENXIO;
2320 goto done;
2321 }
2322 KASSERT(!IS_BUSY(sc), ("%s: controller busy.", __func__));
2323 SET_BUSY(sc);
2324 ADAPTER_UNLOCK(sc);
2325
2326 rc = cxgbe_uninit_synchronized(pi);
2327
2328 ADAPTER_LOCK(sc);
2329 KASSERT(IS_BUSY(sc), ("%s: controller not busy.", __func__));
2330 CLR_BUSY(sc);
2331 wakeup_one(&sc->flags);
2332done:
2333 ADAPTER_UNLOCK(sc);
2334 return (rc);
2335}
2336
2337/*
2338 * Idempotent.
2339 */
2340static int
2341cxgbe_uninit_synchronized(struct port_info *pi)
2342{
2343 struct adapter *sc = pi->adapter;
2344 struct ifnet *ifp = pi->ifp;
2345 int rc;
2346
2318/*
2319 * Idempotent.
2320 */
2321static int
2322cxgbe_uninit_synchronized(struct port_info *pi)
2323{
2324 struct adapter *sc = pi->adapter;
2325 struct ifnet *ifp = pi->ifp;
2326 int rc;
2327
2347 ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
2328 ASSERT_SYNCHRONIZED_OP(sc);
2348
2349 /*
2350 * Disable the VI so that all its data in either direction is discarded
2351 * by the MPS. Leave everything else (the queues, interrupts, and 1Hz
2352 * tick) intact as the TP can deliver negative advice or data that it's
2353 * holding in its RAM (for an offloaded connection) even after the VI is
2354 * disabled.
2355 */
2356 rc = -t4_enable_vi(sc, sc->mbox, pi->viid, false, false);
2357 if (rc) {
2358 if_printf(ifp, "disable_vi failed: %d\n", rc);
2359 return (rc);
2360 }
2361
2362 clrbit(&sc->open_device_map, pi->port_id);
2329
2330 /*
2331 * Disable the VI so that all its data in either direction is discarded
2332 * by the MPS. Leave everything else (the queues, interrupts, and 1Hz
2333 * tick) intact as the TP can deliver negative advice or data that it's
2334 * holding in its RAM (for an offloaded connection) even after the VI is
2335 * disabled.
2336 */
2337 rc = -t4_enable_vi(sc, sc->mbox, pi->viid, false, false);
2338 if (rc) {
2339 if_printf(ifp, "disable_vi failed: %d\n", rc);
2340 return (rc);
2341 }
2342
2343 clrbit(&sc->open_device_map, pi->port_id);
2344 PORT_LOCK(pi);
2363 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
2345 ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
2346 PORT_UNLOCK(pi);
2364
2365 pi->link_cfg.link_ok = 0;
2366 pi->link_cfg.speed = 0;
2367 t4_os_link_changed(sc, pi->port_id, 0);
2368
2369 return (0);
2370}
2371

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

2534port_full_init(struct port_info *pi)
2535{
2536 struct adapter *sc = pi->adapter;
2537 struct ifnet *ifp = pi->ifp;
2538 uint16_t *rss;
2539 struct sge_rxq *rxq;
2540 int rc, i;
2541
2347
2348 pi->link_cfg.link_ok = 0;
2349 pi->link_cfg.speed = 0;
2350 t4_os_link_changed(sc, pi->port_id, 0);
2351
2352 return (0);
2353}
2354

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

2517port_full_init(struct port_info *pi)
2518{
2519 struct adapter *sc = pi->adapter;
2520 struct ifnet *ifp = pi->ifp;
2521 uint16_t *rss;
2522 struct sge_rxq *rxq;
2523 int rc, i;
2524
2542 ADAPTER_LOCK_ASSERT_NOTOWNED(sc);
2525 ASSERT_SYNCHRONIZED_OP(sc);
2543 KASSERT((pi->flags & PORT_INIT_DONE) == 0,
2544 ("%s: PORT_INIT_DONE already", __func__));
2545
2546 sysctl_ctx_init(&pi->ctx);
2547 pi->flags |= PORT_SYSCTL_CTX;
2548
2549 /*
2550 * Allocate tx/rx/fl queues for this port.

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

3519}
3520
3521static int
3522sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS)
3523{
3524 struct port_info *pi = arg1;
3525 struct adapter *sc = pi->adapter;
3526 int idx, rc, i;
2526 KASSERT((pi->flags & PORT_INIT_DONE) == 0,
2527 ("%s: PORT_INIT_DONE already", __func__));
2528
2529 sysctl_ctx_init(&pi->ctx);
2530 pi->flags |= PORT_SYSCTL_CTX;
2531
2532 /*
2533 * Allocate tx/rx/fl queues for this port.

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

3502}
3503
3504static int
3505sysctl_holdoff_tmr_idx(SYSCTL_HANDLER_ARGS)
3506{
3507 struct port_info *pi = arg1;
3508 struct adapter *sc = pi->adapter;
3509 int idx, rc, i;
3510 struct sge_rxq *rxq;
3511 uint8_t v;
3527
3528 idx = pi->tmr_idx;
3529
3530 rc = sysctl_handle_int(oidp, &idx, 0, req);
3531 if (rc != 0 || req->newptr == NULL)
3532 return (rc);
3533
3534 if (idx < 0 || idx >= SGE_NTIMERS)
3535 return (EINVAL);
3536
3512
3513 idx = pi->tmr_idx;
3514
3515 rc = sysctl_handle_int(oidp, &idx, 0, req);
3516 if (rc != 0 || req->newptr == NULL)
3517 return (rc);
3518
3519 if (idx < 0 || idx >= SGE_NTIMERS)
3520 return (EINVAL);
3521
3537 ADAPTER_LOCK(sc);
3538 rc = IS_DOOMED(pi) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
3539 if (rc == 0) {
3540 struct sge_rxq *rxq;
3541 uint8_t v;
3522 rc = begin_synchronized_op(sc, pi, HOLD_LOCK | SLEEP_OK | INTR_OK,
3523 "t4tmr");
3524 if (rc)
3525 return (rc);
3542
3526
3543 v = V_QINTR_TIMER_IDX(idx) | V_QINTR_CNT_EN(pi->pktc_idx != -1);
3544 for_each_rxq(pi, i, rxq) {
3527 v = V_QINTR_TIMER_IDX(idx) | V_QINTR_CNT_EN(pi->pktc_idx != -1);
3528 for_each_rxq(pi, i, rxq) {
3545#ifdef atomic_store_rel_8
3529#ifdef atomic_store_rel_8
3546 atomic_store_rel_8(&rxq->iq.intr_params, v);
3530 atomic_store_rel_8(&rxq->iq.intr_params, v);
3547#else
3531#else
3548 rxq->iq.intr_params = v;
3532 rxq->iq.intr_params = v;
3549#endif
3533#endif
3550 }
3551 pi->tmr_idx = idx;
3552 }
3534 }
3535 pi->tmr_idx = idx;
3553
3536
3554 ADAPTER_UNLOCK(sc);
3555 return (rc);
3537 end_synchronized_op(sc, LOCK_HELD);
3538 return (0);
3556}
3557
3558static int
3559sysctl_holdoff_pktc_idx(SYSCTL_HANDLER_ARGS)
3560{
3561 struct port_info *pi = arg1;
3562 struct adapter *sc = pi->adapter;
3563 int idx, rc;
3564
3565 idx = pi->pktc_idx;
3566
3567 rc = sysctl_handle_int(oidp, &idx, 0, req);
3568 if (rc != 0 || req->newptr == NULL)
3569 return (rc);
3570
3571 if (idx < -1 || idx >= SGE_NCOUNTERS)
3572 return (EINVAL);
3573
3539}
3540
3541static int
3542sysctl_holdoff_pktc_idx(SYSCTL_HANDLER_ARGS)
3543{
3544 struct port_info *pi = arg1;
3545 struct adapter *sc = pi->adapter;
3546 int idx, rc;
3547
3548 idx = pi->pktc_idx;
3549
3550 rc = sysctl_handle_int(oidp, &idx, 0, req);
3551 if (rc != 0 || req->newptr == NULL)
3552 return (rc);
3553
3554 if (idx < -1 || idx >= SGE_NCOUNTERS)
3555 return (EINVAL);
3556
3574 ADAPTER_LOCK(sc);
3575 rc = IS_DOOMED(pi) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
3576 if (rc == 0 && pi->flags & PORT_INIT_DONE)
3577 rc = EBUSY; /* cannot be changed once the queues are created */
3557 rc = begin_synchronized_op(sc, pi, HOLD_LOCK | SLEEP_OK | INTR_OK,
3558 "t4pktc");
3559 if (rc)
3560 return (rc);
3578
3561
3579 if (rc == 0)
3562 if (pi->flags & PORT_INIT_DONE)
3563 rc = EBUSY; /* cannot be changed once the queues are created */
3564 else
3580 pi->pktc_idx = idx;
3581
3565 pi->pktc_idx = idx;
3566
3582 ADAPTER_UNLOCK(sc);
3567 end_synchronized_op(sc, LOCK_HELD);
3583 return (rc);
3584}
3585
3586static int
3587sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS)
3588{
3589 struct port_info *pi = arg1;
3590 struct adapter *sc = pi->adapter;
3591 int qsize, rc;
3592
3593 qsize = pi->qsize_rxq;
3594
3595 rc = sysctl_handle_int(oidp, &qsize, 0, req);
3596 if (rc != 0 || req->newptr == NULL)
3597 return (rc);
3598
3599 if (qsize < 128 || (qsize & 7))
3600 return (EINVAL);
3601
3568 return (rc);
3569}
3570
3571static int
3572sysctl_qsize_rxq(SYSCTL_HANDLER_ARGS)
3573{
3574 struct port_info *pi = arg1;
3575 struct adapter *sc = pi->adapter;
3576 int qsize, rc;
3577
3578 qsize = pi->qsize_rxq;
3579
3580 rc = sysctl_handle_int(oidp, &qsize, 0, req);
3581 if (rc != 0 || req->newptr == NULL)
3582 return (rc);
3583
3584 if (qsize < 128 || (qsize & 7))
3585 return (EINVAL);
3586
3602 ADAPTER_LOCK(sc);
3603 rc = IS_DOOMED(pi) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
3604 if (rc == 0 && pi->flags & PORT_INIT_DONE)
3605 rc = EBUSY; /* cannot be changed once the queues are created */
3587 rc = begin_synchronized_op(sc, pi, HOLD_LOCK | SLEEP_OK | INTR_OK,
3588 "t4rxqs");
3589 if (rc)
3590 return (rc);
3606
3591
3607 if (rc == 0)
3592 if (pi->flags & PORT_INIT_DONE)
3593 rc = EBUSY; /* cannot be changed once the queues are created */
3594 else
3608 pi->qsize_rxq = qsize;
3609
3595 pi->qsize_rxq = qsize;
3596
3610 ADAPTER_UNLOCK(sc);
3597 end_synchronized_op(sc, LOCK_HELD);
3611 return (rc);
3612}
3613
3614static int
3615sysctl_qsize_txq(SYSCTL_HANDLER_ARGS)
3616{
3617 struct port_info *pi = arg1;
3618 struct adapter *sc = pi->adapter;
3619 int qsize, rc;
3620
3621 qsize = pi->qsize_txq;
3622
3623 rc = sysctl_handle_int(oidp, &qsize, 0, req);
3624 if (rc != 0 || req->newptr == NULL)
3625 return (rc);
3626
3598 return (rc);
3599}
3600
3601static int
3602sysctl_qsize_txq(SYSCTL_HANDLER_ARGS)
3603{
3604 struct port_info *pi = arg1;
3605 struct adapter *sc = pi->adapter;
3606 int qsize, rc;
3607
3608 qsize = pi->qsize_txq;
3609
3610 rc = sysctl_handle_int(oidp, &qsize, 0, req);
3611 if (rc != 0 || req->newptr == NULL)
3612 return (rc);
3613
3627 if (qsize < 128)
3614 /* bufring size must be powerof2 */
3615 if (qsize < 128 || !powerof2(qsize))
3628 return (EINVAL);
3629
3616 return (EINVAL);
3617
3630 ADAPTER_LOCK(sc);
3631 rc = IS_DOOMED(pi) ? ENXIO : (IS_BUSY(sc) ? EBUSY : 0);
3632 if (rc == 0 && pi->flags & PORT_INIT_DONE)
3633 rc = EBUSY; /* cannot be changed once the queues are created */
3618 rc = begin_synchronized_op(sc, pi, HOLD_LOCK | SLEEP_OK | INTR_OK,
3619 "t4txqs");
3620 if (rc)
3621 return (rc);
3634
3622
3635 if (rc == 0)
3623 if (pi->flags & PORT_INIT_DONE)
3624 rc = EBUSY; /* cannot be changed once the queues are created */
3625 else
3636 pi->qsize_txq = qsize;
3637
3626 pi->qsize_txq = qsize;
3627
3638 ADAPTER_UNLOCK(sc);
3628 end_synchronized_op(sc, LOCK_HELD);
3639 return (rc);
3640}
3641
3642static int
3643sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS)
3644{
3645 struct adapter *sc = arg1;
3646 int reg = arg2;

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

4669 fconf |= F_FCOE;
4670
4671 return (fconf);
4672}
4673
4674static int
4675get_filter_mode(struct adapter *sc, uint32_t *mode)
4676{
3629 return (rc);
3630}
3631
3632static int
3633sysctl_handle_t4_reg64(SYSCTL_HANDLER_ARGS)
3634{
3635 struct adapter *sc = arg1;
3636 int reg = arg2;

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

4659 fconf |= F_FCOE;
4660
4661 return (fconf);
4662}
4663
4664static int
4665get_filter_mode(struct adapter *sc, uint32_t *mode)
4666{
4667 int rc;
4677 uint32_t fconf;
4678
4668 uint32_t fconf;
4669
4670 rc = begin_synchronized_op(sc, NULL, HOLD_LOCK | SLEEP_OK | INTR_OK,
4671 "t4getfm");
4672 if (rc)
4673 return (rc);
4674
4679 t4_read_indirect(sc, A_TP_PIO_ADDR, A_TP_PIO_DATA, &fconf, 1,
4680 A_TP_VLAN_PRI_MAP);
4681
4682 if (sc->filter_mode != fconf) {
4683 log(LOG_WARNING, "%s: cached filter mode out of sync %x %x.\n",
4684 device_get_nameunit(sc->dev), sc->filter_mode, fconf);
4685 sc->filter_mode = fconf;
4686 }
4687
4688 *mode = fconf_to_mode(sc->filter_mode);
4689
4675 t4_read_indirect(sc, A_TP_PIO_ADDR, A_TP_PIO_DATA, &fconf, 1,
4676 A_TP_VLAN_PRI_MAP);
4677
4678 if (sc->filter_mode != fconf) {
4679 log(LOG_WARNING, "%s: cached filter mode out of sync %x %x.\n",
4680 device_get_nameunit(sc->dev), sc->filter_mode, fconf);
4681 sc->filter_mode = fconf;
4682 }
4683
4684 *mode = fconf_to_mode(sc->filter_mode);
4685
4686 end_synchronized_op(sc, LOCK_HELD);
4690 return (0);
4691}
4692
4693static int
4694set_filter_mode(struct adapter *sc, uint32_t mode)
4695{
4696 uint32_t fconf;
4697 int rc;
4698
4699 fconf = mode_to_fconf(mode);
4700
4687 return (0);
4688}
4689
4690static int
4691set_filter_mode(struct adapter *sc, uint32_t mode)
4692{
4693 uint32_t fconf;
4694 int rc;
4695
4696 fconf = mode_to_fconf(mode);
4697
4701 ADAPTER_LOCK(sc);
4702 if (IS_BUSY(sc)) {
4703 rc = EAGAIN;
4704 goto done;
4705 }
4698 rc = begin_synchronized_op(sc, NULL, HOLD_LOCK | SLEEP_OK | INTR_OK,
4699 "t4setfm");
4700 if (rc)
4701 return (rc);
4706
4707 if (sc->tids.ftids_in_use > 0) {
4708 rc = EBUSY;
4709 goto done;
4710 }
4711
4712#ifdef TCP_OFFLOAD
4713 if (sc->offload_map) {

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

4720 rc = -t4_set_filter_mode(sc, fconf);
4721 if (rc == 0)
4722 sc->filter_mode = fconf;
4723#else
4724 rc = ENOTSUP;
4725#endif
4726
4727done:
4702
4703 if (sc->tids.ftids_in_use > 0) {
4704 rc = EBUSY;
4705 goto done;
4706 }
4707
4708#ifdef TCP_OFFLOAD
4709 if (sc->offload_map) {

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

4716 rc = -t4_set_filter_mode(sc, fconf);
4717 if (rc == 0)
4718 sc->filter_mode = fconf;
4719#else
4720 rc = ENOTSUP;
4721#endif
4722
4723done:
4728 ADAPTER_UNLOCK(sc);
4724 end_synchronized_op(sc, LOCK_HELD);
4729 return (rc);
4730}
4731
4732static inline uint64_t
4733get_filter_hits(struct adapter *sc, uint32_t fid)
4734{
4735 uint32_t tcb_base = t4_read_reg(sc, A_TP_CMM_TCB_BASE);
4736 uint64_t hits;

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

4741 hits = t4_read_reg64(sc, MEMWIN0_BASE + 16);
4742
4743 return (be64toh(hits));
4744}
4745
4746static int
4747get_filter(struct adapter *sc, struct t4_filter *t)
4748{
4725 return (rc);
4726}
4727
4728static inline uint64_t
4729get_filter_hits(struct adapter *sc, uint32_t fid)
4730{
4731 uint32_t tcb_base = t4_read_reg(sc, A_TP_CMM_TCB_BASE);
4732 uint64_t hits;

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

4737 hits = t4_read_reg64(sc, MEMWIN0_BASE + 16);
4738
4739 return (be64toh(hits));
4740}
4741
4742static int
4743get_filter(struct adapter *sc, struct t4_filter *t)
4744{
4749 int i, nfilters = sc->tids.nftids;
4745 int i, rc, nfilters = sc->tids.nftids;
4750 struct filter_entry *f;
4751
4746 struct filter_entry *f;
4747
4752 ADAPTER_LOCK_ASSERT_OWNED(sc);
4748 rc = begin_synchronized_op(sc, NULL, HOLD_LOCK | SLEEP_OK | INTR_OK,
4749 "t4getf");
4750 if (rc)
4751 return (rc);
4753
4752
4754 if (IS_BUSY(sc))
4755 return (EAGAIN);
4756
4757 if (sc->tids.ftids_in_use == 0 || sc->tids.ftid_tab == NULL ||
4758 t->idx >= nfilters) {
4759 t->idx = 0xffffffff;
4753 if (sc->tids.ftids_in_use == 0 || sc->tids.ftid_tab == NULL ||
4754 t->idx >= nfilters) {
4755 t->idx = 0xffffffff;
4760 return (0);
4756 goto done;
4761 }
4762
4763 f = &sc->tids.ftid_tab[t->idx];
4764 for (i = t->idx; i < nfilters; i++, f++) {
4765 if (f->valid) {
4766 t->idx = i;
4767 t->l2tidx = f->l2t ? f->l2t->idx : 0;
4768 t->smtidx = f->smtidx;
4769 if (f->fs.hitcnts)
4770 t->hits = get_filter_hits(sc, t->idx);
4771 else
4772 t->hits = UINT64_MAX;
4773 t->fs = f->fs;
4774
4757 }
4758
4759 f = &sc->tids.ftid_tab[t->idx];
4760 for (i = t->idx; i < nfilters; i++, f++) {
4761 if (f->valid) {
4762 t->idx = i;
4763 t->l2tidx = f->l2t ? f->l2t->idx : 0;
4764 t->smtidx = f->smtidx;
4765 if (f->fs.hitcnts)
4766 t->hits = get_filter_hits(sc, t->idx);
4767 else
4768 t->hits = UINT64_MAX;
4769 t->fs = f->fs;
4770
4775 return (0);
4771 goto done;
4776 }
4777 }
4778
4779 t->idx = 0xffffffff;
4772 }
4773 }
4774
4775 t->idx = 0xffffffff;
4776done:
4777 end_synchronized_op(sc, LOCK_HELD);
4780 return (0);
4781}
4782
4783static int
4784set_filter(struct adapter *sc, struct t4_filter *t)
4785{
4786 unsigned int nfilters, nports;
4787 struct filter_entry *f;
4778 return (0);
4779}
4780
4781static int
4782set_filter(struct adapter *sc, struct t4_filter *t)
4783{
4784 unsigned int nfilters, nports;
4785 struct filter_entry *f;
4788 int i;
4786 int i, rc;
4789
4787
4790 ADAPTER_LOCK_ASSERT_OWNED(sc);
4788 rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4setf");
4789 if (rc)
4790 return (rc);
4791
4792 nfilters = sc->tids.nftids;
4793 nports = sc->params.nports;
4794
4791
4792 nfilters = sc->tids.nftids;
4793 nports = sc->params.nports;
4794
4795 if (nfilters == 0)
4796 return (ENOTSUP);
4795 if (nfilters == 0) {
4796 rc = ENOTSUP;
4797 goto done;
4798 }
4797
4799
4798 if (!(sc->flags & FULL_INIT_DONE))
4799 return (EAGAIN);
4800 if (!(sc->flags & FULL_INIT_DONE)) {
4801 rc = EAGAIN;
4802 goto done;
4803 }
4800
4804
4801 if (t->idx >= nfilters)
4802 return (EINVAL);
4805 if (t->idx >= nfilters) {
4806 rc = EINVAL;
4807 goto done;
4808 }
4803
4804 /* Validate against the global filter mode */
4809
4810 /* Validate against the global filter mode */
4805 if ((sc->filter_mode | fspec_to_fconf(&t->fs)) != sc->filter_mode)
4806 return (E2BIG);
4811 if ((sc->filter_mode | fspec_to_fconf(&t->fs)) != sc->filter_mode) {
4812 rc = E2BIG;
4813 goto done;
4814 }
4807
4815
4808 if (t->fs.action == FILTER_SWITCH && t->fs.eport >= nports)
4809 return (EINVAL);
4816 if (t->fs.action == FILTER_SWITCH && t->fs.eport >= nports) {
4817 rc = EINVAL;
4818 goto done;
4819 }
4810
4820
4811 if (t->fs.val.iport >= nports)
4812 return (EINVAL);
4821 if (t->fs.val.iport >= nports) {
4822 rc = EINVAL;
4823 goto done;
4824 }
4813
4814 /* Can't specify an iq if not steering to it */
4825
4826 /* Can't specify an iq if not steering to it */
4815 if (!t->fs.dirsteer && t->fs.iq)
4816 return (EINVAL);
4827 if (!t->fs.dirsteer && t->fs.iq) {
4828 rc = EINVAL;
4829 goto done;
4830 }
4817
4818 /* IPv6 filter idx must be 4 aligned */
4819 if (t->fs.type == 1 &&
4831
4832 /* IPv6 filter idx must be 4 aligned */
4833 if (t->fs.type == 1 &&
4820 ((t->idx & 0x3) || t->idx + 4 >= nfilters))
4821 return (EINVAL);
4834 ((t->idx & 0x3) || t->idx + 4 >= nfilters)) {
4835 rc = EINVAL;
4836 goto done;
4837 }
4822
4823 if (sc->tids.ftid_tab == NULL) {
4824 KASSERT(sc->tids.ftids_in_use == 0,
4825 ("%s: no memory allocated but filters_in_use > 0",
4826 __func__));
4827
4828 sc->tids.ftid_tab = malloc(sizeof (struct filter_entry) *
4829 nfilters, M_CXGBE, M_NOWAIT | M_ZERO);
4838
4839 if (sc->tids.ftid_tab == NULL) {
4840 KASSERT(sc->tids.ftids_in_use == 0,
4841 ("%s: no memory allocated but filters_in_use > 0",
4842 __func__));
4843
4844 sc->tids.ftid_tab = malloc(sizeof (struct filter_entry) *
4845 nfilters, M_CXGBE, M_NOWAIT | M_ZERO);
4830 if (sc->tids.ftid_tab == NULL)
4831 return (ENOMEM);
4846 if (sc->tids.ftid_tab == NULL) {
4847 rc = ENOMEM;
4848 goto done;
4849 }
4850 mtx_init(&sc->tids.ftid_lock, "T4 filters", 0, MTX_DEF);
4832 }
4833
4834 for (i = 0; i < 4; i++) {
4835 f = &sc->tids.ftid_tab[t->idx + i];
4836
4851 }
4852
4853 for (i = 0; i < 4; i++) {
4854 f = &sc->tids.ftid_tab[t->idx + i];
4855
4837 if (f->pending || f->valid)
4838 return (EBUSY);
4839 if (f->locked)
4840 return (EPERM);
4856 if (f->pending || f->valid) {
4857 rc = EBUSY;
4858 goto done;
4859 }
4860 if (f->locked) {
4861 rc = EPERM;
4862 goto done;
4863 }
4841
4842 if (t->fs.type == 0)
4843 break;
4844 }
4845
4846 f = &sc->tids.ftid_tab[t->idx];
4847 f->fs = t->fs;
4848
4864
4865 if (t->fs.type == 0)
4866 break;
4867 }
4868
4869 f = &sc->tids.ftid_tab[t->idx];
4870 f->fs = t->fs;
4871
4849 return set_filter_wr(sc, t->idx);
4872 rc = set_filter_wr(sc, t->idx);
4873done:
4874 end_synchronized_op(sc, 0);
4875
4876 if (rc == 0) {
4877 mtx_lock(&sc->tids.ftid_lock);
4878 for (;;) {
4879 if (f->pending == 0) {
4880 rc = f->valid ? 0 : EIO;
4881 break;
4882 }
4883
4884 if (mtx_sleep(&sc->tids.ftid_tab, &sc->tids.ftid_lock,
4885 PCATCH, "t4setfw", 0)) {
4886 rc = EINPROGRESS;
4887 break;
4888 }
4889 }
4890 mtx_unlock(&sc->tids.ftid_lock);
4891 }
4892 return (rc);
4850}
4851
4852static int
4853del_filter(struct adapter *sc, struct t4_filter *t)
4854{
4855 unsigned int nfilters;
4856 struct filter_entry *f;
4893}
4894
4895static int
4896del_filter(struct adapter *sc, struct t4_filter *t)
4897{
4898 unsigned int nfilters;
4899 struct filter_entry *f;
4900 int rc;
4857
4901
4858 ADAPTER_LOCK_ASSERT_OWNED(sc);
4902 rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4delf");
4903 if (rc)
4904 return (rc);
4859
4905
4860 if (IS_BUSY(sc))
4861 return (EAGAIN);
4862
4863 nfilters = sc->tids.nftids;
4864
4906 nfilters = sc->tids.nftids;
4907
4865 if (nfilters == 0)
4866 return (ENOTSUP);
4908 if (nfilters == 0) {
4909 rc = ENOTSUP;
4910 goto done;
4911 }
4867
4868 if (sc->tids.ftid_tab == NULL || sc->tids.ftids_in_use == 0 ||
4912
4913 if (sc->tids.ftid_tab == NULL || sc->tids.ftids_in_use == 0 ||
4869 t->idx >= nfilters)
4870 return (EINVAL);
4914 t->idx >= nfilters) {
4915 rc = EINVAL;
4916 goto done;
4917 }
4871
4918
4872 if (!(sc->flags & FULL_INIT_DONE))
4873 return (EAGAIN);
4919 if (!(sc->flags & FULL_INIT_DONE)) {
4920 rc = EAGAIN;
4921 goto done;
4922 }
4874
4875 f = &sc->tids.ftid_tab[t->idx];
4876
4923
4924 f = &sc->tids.ftid_tab[t->idx];
4925
4877 if (f->pending)
4878 return (EBUSY);
4879 if (f->locked)
4880 return (EPERM);
4926 if (f->pending) {
4927 rc = EBUSY;
4928 goto done;
4929 }
4930 if (f->locked) {
4931 rc = EPERM;
4932 goto done;
4933 }
4881
4882 if (f->valid) {
4883 t->fs = f->fs; /* extra info for the caller */
4934
4935 if (f->valid) {
4936 t->fs = f->fs; /* extra info for the caller */
4884 return del_filter_wr(sc, t->idx);
4937 rc = del_filter_wr(sc, t->idx);
4885 }
4886
4938 }
4939
4887 return (0);
4940done:
4941 end_synchronized_op(sc, 0);
4942
4943 if (rc == 0) {
4944 mtx_lock(&sc->tids.ftid_lock);
4945 for (;;) {
4946 if (f->pending == 0) {
4947 rc = f->valid ? EIO : 0;
4948 break;
4949 }
4950
4951 if (mtx_sleep(&sc->tids.ftid_tab, &sc->tids.ftid_lock,
4952 PCATCH, "t4delfw", 0)) {
4953 rc = EINPROGRESS;
4954 break;
4955 }
4956 }
4957 mtx_unlock(&sc->tids.ftid_lock);
4958 }
4959
4960 return (rc);
4888}
4889
4890static void
4891clear_filter(struct filter_entry *f)
4892{
4893 if (f->l2t)
4894 t4_l2t_release(f->l2t);
4895
4896 bzero(f, sizeof (*f));
4897}
4898
4899static int
4900set_filter_wr(struct adapter *sc, int fidx)
4901{
4902 struct filter_entry *f = &sc->tids.ftid_tab[fidx];
4903 struct wrqe *wr;
4904 struct fw_filter_wr *fwr;
4905 unsigned int ftid;
4906
4961}
4962
4963static void
4964clear_filter(struct filter_entry *f)
4965{
4966 if (f->l2t)
4967 t4_l2t_release(f->l2t);
4968
4969 bzero(f, sizeof (*f));
4970}
4971
4972static int
4973set_filter_wr(struct adapter *sc, int fidx)
4974{
4975 struct filter_entry *f = &sc->tids.ftid_tab[fidx];
4976 struct wrqe *wr;
4977 struct fw_filter_wr *fwr;
4978 unsigned int ftid;
4979
4907 ADAPTER_LOCK_ASSERT_OWNED(sc);
4980 ASSERT_SYNCHRONIZED_OP(sc);
4908
4909 if (f->fs.newdmac || f->fs.newvlan) {
4910 /* This filter needs an L2T entry; allocate one. */
4911 f->l2t = t4_l2t_alloc_switching(sc->l2t);
4912 if (f->l2t == NULL)
4913 return (EAGAIN);
4914 if (t4_l2t_set_switching(sc, f->l2t, f->fs.vlan, f->fs.eport,
4915 f->fs.dmac)) {

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

5002static int
5003del_filter_wr(struct adapter *sc, int fidx)
5004{
5005 struct filter_entry *f = &sc->tids.ftid_tab[fidx];
5006 struct wrqe *wr;
5007 struct fw_filter_wr *fwr;
5008 unsigned int ftid;
5009
4981
4982 if (f->fs.newdmac || f->fs.newvlan) {
4983 /* This filter needs an L2T entry; allocate one. */
4984 f->l2t = t4_l2t_alloc_switching(sc->l2t);
4985 if (f->l2t == NULL)
4986 return (EAGAIN);
4987 if (t4_l2t_set_switching(sc, f->l2t, f->fs.vlan, f->fs.eport,
4988 f->fs.dmac)) {

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

5075static int
5076del_filter_wr(struct adapter *sc, int fidx)
5077{
5078 struct filter_entry *f = &sc->tids.ftid_tab[fidx];
5079 struct wrqe *wr;
5080 struct fw_filter_wr *fwr;
5081 unsigned int ftid;
5082
5010 ADAPTER_LOCK_ASSERT_OWNED(sc);
5011
5012 ftid = sc->tids.ftid_base + fidx;
5013
5014 wr = alloc_wrqe(sizeof(*fwr), &sc->sge.mgmtq);
5015 if (wr == NULL)
5016 return (ENOMEM);
5017 fwr = wrtod(wr);
5018 bzero(fwr, sizeof (*fwr));
5019

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

5034 KASSERT(m == NULL, ("%s: payload with opcode %02x", __func__,
5035 rss->opcode));
5036
5037 if (idx >= sc->tids.ftid_base &&
5038 (idx -= sc->tids.ftid_base) < sc->tids.nftids) {
5039 unsigned int rc = G_COOKIE(rpl->cookie);
5040 struct filter_entry *f = &sc->tids.ftid_tab[idx];
5041
5083 ftid = sc->tids.ftid_base + fidx;
5084
5085 wr = alloc_wrqe(sizeof(*fwr), &sc->sge.mgmtq);
5086 if (wr == NULL)
5087 return (ENOMEM);
5088 fwr = wrtod(wr);
5089 bzero(fwr, sizeof (*fwr));
5090

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

5105 KASSERT(m == NULL, ("%s: payload with opcode %02x", __func__,
5106 rss->opcode));
5107
5108 if (idx >= sc->tids.ftid_base &&
5109 (idx -= sc->tids.ftid_base) < sc->tids.nftids) {
5110 unsigned int rc = G_COOKIE(rpl->cookie);
5111 struct filter_entry *f = &sc->tids.ftid_tab[idx];
5112
5042 ADAPTER_LOCK(sc);
5113 mtx_lock(&sc->tids.ftid_lock);
5043 if (rc == FW_FILTER_WR_FLT_ADDED) {
5114 if (rc == FW_FILTER_WR_FLT_ADDED) {
5115 KASSERT(f->pending, ("%s: filter[%u] isn't pending.",
5116 __func__, idx));
5044 f->smtidx = (be64toh(rpl->oldval) >> 24) & 0xff;
5045 f->pending = 0; /* asynchronous setup completed */
5046 f->valid = 1;
5047 } else {
5048 if (rc != FW_FILTER_WR_FLT_DELETED) {
5049 /* Add or delete failed, display an error */
5050 log(LOG_ERR,
5051 "filter %u setup failed with error %u\n",
5052 idx, rc);
5053 }
5054
5055 clear_filter(f);
5056 sc->tids.ftids_in_use--;
5057 }
5117 f->smtidx = (be64toh(rpl->oldval) >> 24) & 0xff;
5118 f->pending = 0; /* asynchronous setup completed */
5119 f->valid = 1;
5120 } else {
5121 if (rc != FW_FILTER_WR_FLT_DELETED) {
5122 /* Add or delete failed, display an error */
5123 log(LOG_ERR,
5124 "filter %u setup failed with error %u\n",
5125 idx, rc);
5126 }
5127
5128 clear_filter(f);
5129 sc->tids.ftids_in_use--;
5130 }
5058 ADAPTER_UNLOCK(sc);
5131 wakeup(&sc->tids.ftid_tab);
5132 mtx_unlock(&sc->tids.ftid_lock);
5059 }
5060
5061 return (0);
5062}
5063
5064static int
5065get_sge_context(struct adapter *sc, struct t4_sge_context *cntxt)
5066{
5133 }
5134
5135 return (0);
5136}
5137
5138static int
5139get_sge_context(struct adapter *sc, struct t4_sge_context *cntxt)
5140{
5067 int rc = EINVAL;
5141 int rc;
5068
5069 if (cntxt->cid > M_CTXTQID)
5142
5143 if (cntxt->cid > M_CTXTQID)
5070 return (rc);
5144 return (EINVAL);
5071
5072 if (cntxt->mem_id != CTXT_EGRESS && cntxt->mem_id != CTXT_INGRESS &&
5073 cntxt->mem_id != CTXT_FLM && cntxt->mem_id != CTXT_CNM)
5145
5146 if (cntxt->mem_id != CTXT_EGRESS && cntxt->mem_id != CTXT_INGRESS &&
5147 cntxt->mem_id != CTXT_FLM && cntxt->mem_id != CTXT_CNM)
5074 return (rc);
5148 return (EINVAL);
5075
5076 if (sc->flags & FW_OK) {
5149
5150 if (sc->flags & FW_OK) {
5077 ADAPTER_LOCK(sc); /* Avoid parallel t4_wr_mbox */
5078 rc = -t4_sge_ctxt_rd(sc, sc->mbox, cntxt->cid, cntxt->mem_id,
5079 &cntxt->data[0]);
5080 ADAPTER_UNLOCK(sc);
5151 rc = begin_synchronized_op(sc, NULL, HOLD_LOCK, "t4ctxt");
5152 if (rc == 0) {
5153 rc = -t4_sge_ctxt_rd(sc, sc->mbox, cntxt->cid,
5154 cntxt->mem_id, &cntxt->data[0]);
5155 end_synchronized_op(sc, LOCK_HELD);
5156 if (rc == 0)
5157 return (0);
5158 }
5081 }
5082
5159 }
5160
5083 if (rc != 0) {
5084 /* Read via firmware failed or wasn't even attempted */
5161 /*
5162 * Read via firmware failed or wasn't even attempted. Read directly via
5163 * the backdoor.
5164 */
5165 rc = -t4_sge_ctxt_rd_bd(sc, cntxt->cid, cntxt->mem_id,
5166 &cntxt->data[0]);
5167 return (rc);
5168}
5085
5169
5086 rc = -t4_sge_ctxt_rd_bd(sc, cntxt->cid, cntxt->mem_id,
5087 &cntxt->data[0]);
5170static int
5171load_fw(struct adapter *sc, struct t4_data *fw)
5172{
5173 int rc;
5174 uint8_t *fw_data;
5175
5176 rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4ldfw");
5177 if (rc)
5178 return (rc);
5179
5180 if (sc->flags & FULL_INIT_DONE) {
5181 rc = EBUSY;
5182 goto done;
5088 }
5089
5183 }
5184
5185 fw_data = malloc(fw->len, M_CXGBE, M_WAITOK);
5186 if (fw_data == NULL) {
5187 rc = ENOMEM;
5188 goto done;
5189 }
5190
5191 rc = copyin(fw->data, fw_data, fw->len);
5192 if (rc == 0)
5193 rc = -t4_load_fw(sc, fw_data, fw->len);
5194
5195 free(fw_data, M_CXGBE);
5196done:
5197 end_synchronized_op(sc, 0);
5090 return (rc);
5091}
5092
5093static int
5094read_card_mem(struct adapter *sc, struct t4_mem_range *mr)
5095{
5096 uint32_t base, size, lo, hi, win, off, remaining, i, n;
5097 uint32_t *buf, *b;

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

5168 return (rc);
5169}
5170
5171static int
5172read_i2c(struct adapter *sc, struct t4_i2c_data *i2cd)
5173{
5174 int rc;
5175
5198 return (rc);
5199}
5200
5201static int
5202read_card_mem(struct adapter *sc, struct t4_mem_range *mr)
5203{
5204 uint32_t base, size, lo, hi, win, off, remaining, i, n;
5205 uint32_t *buf, *b;

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

5276 return (rc);
5277}
5278
5279static int
5280read_i2c(struct adapter *sc, struct t4_i2c_data *i2cd)
5281{
5282 int rc;
5283
5176 ADAPTER_LOCK_ASSERT_OWNED(sc); /* for mbox */
5177
5178 if (i2cd->len == 0 || i2cd->port_id >= sc->params.nports)
5179 return (EINVAL);
5180
5181 if (i2cd->len > 1) {
5182 /* XXX: need fw support for longer reads in one go */
5183 return (ENOTSUP);
5184 }
5185
5284 if (i2cd->len == 0 || i2cd->port_id >= sc->params.nports)
5285 return (EINVAL);
5286
5287 if (i2cd->len > 1) {
5288 /* XXX: need fw support for longer reads in one go */
5289 return (ENOTSUP);
5290 }
5291
5292 rc = begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4i2crd");
5293 if (rc)
5294 return (rc);
5186 rc = -t4_i2c_rd(sc, sc->mbox, i2cd->port_id, i2cd->dev_addr,
5187 i2cd->offset, &i2cd->data[0]);
5295 rc = -t4_i2c_rd(sc, sc->mbox, i2cd->port_id, i2cd->dev_addr,
5296 i2cd->offset, &i2cd->data[0]);
5297 end_synchronized_op(sc, 0);
5188
5189 return (rc);
5190}
5191
5192int
5193t4_os_find_pci_capability(struct adapter *sc, int cap)
5194{
5195 int i;

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

5349 }
5350 case CHELSIO_T4_GET_FILTER_MODE:
5351 rc = get_filter_mode(sc, (uint32_t *)data);
5352 break;
5353 case CHELSIO_T4_SET_FILTER_MODE:
5354 rc = set_filter_mode(sc, *(uint32_t *)data);
5355 break;
5356 case CHELSIO_T4_GET_FILTER:
5298
5299 return (rc);
5300}
5301
5302int
5303t4_os_find_pci_capability(struct adapter *sc, int cap)
5304{
5305 int i;

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

5459 }
5460 case CHELSIO_T4_GET_FILTER_MODE:
5461 rc = get_filter_mode(sc, (uint32_t *)data);
5462 break;
5463 case CHELSIO_T4_SET_FILTER_MODE:
5464 rc = set_filter_mode(sc, *(uint32_t *)data);
5465 break;
5466 case CHELSIO_T4_GET_FILTER:
5357 ADAPTER_LOCK(sc);
5358 rc = get_filter(sc, (struct t4_filter *)data);
5467 rc = get_filter(sc, (struct t4_filter *)data);
5359 ADAPTER_UNLOCK(sc);
5360 break;
5361 case CHELSIO_T4_SET_FILTER:
5468 break;
5469 case CHELSIO_T4_SET_FILTER:
5362 ADAPTER_LOCK(sc);
5363 rc = set_filter(sc, (struct t4_filter *)data);
5470 rc = set_filter(sc, (struct t4_filter *)data);
5364 ADAPTER_UNLOCK(sc);
5365 break;
5366 case CHELSIO_T4_DEL_FILTER:
5471 break;
5472 case CHELSIO_T4_DEL_FILTER:
5367 ADAPTER_LOCK(sc);
5368 rc = del_filter(sc, (struct t4_filter *)data);
5473 rc = del_filter(sc, (struct t4_filter *)data);
5369 ADAPTER_UNLOCK(sc);
5370 break;
5371 case CHELSIO_T4_GET_SGE_CONTEXT:
5372 rc = get_sge_context(sc, (struct t4_sge_context *)data);
5373 break;
5474 break;
5475 case CHELSIO_T4_GET_SGE_CONTEXT:
5476 rc = get_sge_context(sc, (struct t4_sge_context *)data);
5477 break;
5374 case CHELSIO_T4_LOAD_FW: {
5375 struct t4_data *fw = (struct t4_data *)data;
5376 uint8_t *fw_data;
5377
5378 if (sc->flags & FULL_INIT_DONE)
5379 return (EBUSY);
5380
5381 fw_data = malloc(fw->len, M_CXGBE, M_NOWAIT);
5382 if (fw_data == NULL)
5383 return (ENOMEM);
5384
5385 rc = copyin(fw->data, fw_data, fw->len);
5386 if (rc == 0)
5387 rc = -t4_load_fw(sc, fw_data, fw->len);
5388
5389 free(fw_data, M_CXGBE);
5478 case CHELSIO_T4_LOAD_FW:
5479 rc = load_fw(sc, (struct t4_data *)data);
5390 break;
5480 break;
5391 }
5392 case CHELSIO_T4_GET_MEM:
5393 rc = read_card_mem(sc, (struct t4_mem_range *)data);
5394 break;
5395 case CHELSIO_T4_GET_I2C:
5481 case CHELSIO_T4_GET_MEM:
5482 rc = read_card_mem(sc, (struct t4_mem_range *)data);
5483 break;
5484 case CHELSIO_T4_GET_I2C:
5396 ADAPTER_LOCK(sc);
5397 rc = read_i2c(sc, (struct t4_i2c_data *)data);
5485 rc = read_i2c(sc, (struct t4_i2c_data *)data);
5398 ADAPTER_UNLOCK(sc);
5399 break;
5400 case CHELSIO_T4_CLEAR_STATS: {
5401 u_int port_id = *(uint32_t *)data;
5402
5403 if (port_id >= sc->params.nports)
5404 return (EINVAL);
5405
5406 t4_clr_port_stats(sc, port_id);

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

5415
5416#ifdef TCP_OFFLOAD
5417static int
5418toe_capability(struct port_info *pi, int enable)
5419{
5420 int rc;
5421 struct adapter *sc = pi->adapter;
5422
5486 break;
5487 case CHELSIO_T4_CLEAR_STATS: {
5488 u_int port_id = *(uint32_t *)data;
5489
5490 if (port_id >= sc->params.nports)
5491 return (EINVAL);
5492
5493 t4_clr_port_stats(sc, port_id);

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

5502
5503#ifdef TCP_OFFLOAD
5504static int
5505toe_capability(struct port_info *pi, int enable)
5506{
5507 int rc;
5508 struct adapter *sc = pi->adapter;
5509
5423 ADAPTER_LOCK_ASSERT_OWNED(sc);
5510 ASSERT_SYNCHRONIZED_OP(sc);
5424
5425 if (!is_offload(sc))
5426 return (ENODEV);
5427
5428 if (enable) {
5429 if (!(sc->flags & FULL_INIT_DONE)) {
5511
5512 if (!is_offload(sc))
5513 return (ENODEV);
5514
5515 if (enable) {
5516 if (!(sc->flags & FULL_INIT_DONE)) {
5430 log(LOG_WARNING,
5431 "You must enable a cxgbe interface first\n");
5432 return (EAGAIN);
5517 rc = cxgbe_init_synchronized(pi);
5518 if (rc)
5519 return (rc);
5433 }
5434
5435 if (isset(&sc->offload_map, pi->port_id))
5436 return (0);
5437
5438 if (!(sc->flags & TOM_INIT_DONE)) {
5439 rc = t4_activate_uld(sc, ULD_TOM);
5440 if (rc == EAGAIN) {

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

5513}
5514
5515int
5516t4_activate_uld(struct adapter *sc, int id)
5517{
5518 int rc = EAGAIN;
5519 struct uld_info *ui;
5520
5520 }
5521
5522 if (isset(&sc->offload_map, pi->port_id))
5523 return (0);
5524
5525 if (!(sc->flags & TOM_INIT_DONE)) {
5526 rc = t4_activate_uld(sc, ULD_TOM);
5527 if (rc == EAGAIN) {

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

5600}
5601
5602int
5603t4_activate_uld(struct adapter *sc, int id)
5604{
5605 int rc = EAGAIN;
5606 struct uld_info *ui;
5607
5608 ASSERT_SYNCHRONIZED_OP(sc);
5609
5521 mtx_lock(&t4_uld_list_lock);
5522
5523 SLIST_FOREACH(ui, &t4_uld_list, link) {
5524 if (ui->uld_id == id) {
5525 rc = ui->activate(sc);
5526 if (rc == 0)
5527 ui->refcount++;
5528 goto done;

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

5535}
5536
5537int
5538t4_deactivate_uld(struct adapter *sc, int id)
5539{
5540 int rc = EINVAL;
5541 struct uld_info *ui;
5542
5610 mtx_lock(&t4_uld_list_lock);
5611
5612 SLIST_FOREACH(ui, &t4_uld_list, link) {
5613 if (ui->uld_id == id) {
5614 rc = ui->activate(sc);
5615 if (rc == 0)
5616 ui->refcount++;
5617 goto done;

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

5624}
5625
5626int
5627t4_deactivate_uld(struct adapter *sc, int id)
5628{
5629 int rc = EINVAL;
5630 struct uld_info *ui;
5631
5632 ASSERT_SYNCHRONIZED_OP(sc);
5633
5543 mtx_lock(&t4_uld_list_lock);
5544
5545 SLIST_FOREACH(ui, &t4_uld_list, link) {
5546 if (ui->uld_id == id) {
5547 rc = ui->deactivate(sc);
5548 if (rc == 0)
5549 ui->refcount--;
5550 goto done;

--- 123 unchanged lines hidden ---
5634 mtx_lock(&t4_uld_list_lock);
5635
5636 SLIST_FOREACH(ui, &t4_uld_list, link) {
5637 if (ui->uld_id == id) {
5638 rc = ui->deactivate(sc);
5639 if (rc == 0)
5640 ui->refcount--;
5641 goto done;

--- 123 unchanged lines hidden ---