Deleted Added
full compact
if_mxge.c (172162) if_mxge.c (175365)
1/******************************************************************************
2
1/******************************************************************************
2
3Copyright (c) 2006-2007, Myricom Inc.
3Copyright (c) 2006-2008, Myricom 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
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11

--- 11 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>
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
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
11

--- 11 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/mxge/if_mxge.c 172162 2007-09-13 21:29:02Z gallatin $");
31__FBSDID("$FreeBSD: head/sys/dev/mxge/if_mxge.c 175365 2008-01-15 20:34:49Z gallatin $");
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/linker.h>
36#include <sys/firmware.h>
37#include <sys/endian.h>
38#include <sys/sockio.h>
39#include <sys/mbuf.h>

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

64#include <netinet/ip.h>
65#include <netinet/tcp.h>
66
67#include <machine/bus.h>
68#include <machine/in_cksum.h>
69#include <machine/resource.h>
70#include <sys/bus.h>
71#include <sys/rman.h>
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/linker.h>
36#include <sys/firmware.h>
37#include <sys/endian.h>
38#include <sys/sockio.h>
39#include <sys/mbuf.h>

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

64#include <netinet/ip.h>
65#include <netinet/tcp.h>
66
67#include <machine/bus.h>
68#include <machine/in_cksum.h>
69#include <machine/resource.h>
70#include <sys/bus.h>
71#include <sys/rman.h>
72#include <sys/smp.h>
72
73#include <dev/pci/pcireg.h>
74#include <dev/pci/pcivar.h>
75
76#include <vm/vm.h> /* for pmap_mapdev() */
77#include <vm/pmap.h>
78
79#if defined(__i386) || defined(__amd64)
80#include <machine/specialreg.h>
81#endif
82
83#include <dev/mxge/mxge_mcp.h>
84#include <dev/mxge/mcp_gen_header.h>
73
74#include <dev/pci/pcireg.h>
75#include <dev/pci/pcivar.h>
76
77#include <vm/vm.h> /* for pmap_mapdev() */
78#include <vm/pmap.h>
79
80#if defined(__i386) || defined(__amd64)
81#include <machine/specialreg.h>
82#endif
83
84#include <dev/mxge/mxge_mcp.h>
85#include <dev/mxge/mcp_gen_header.h>
86/*#define MXGE_FAKE_IFP*/
85#include <dev/mxge/if_mxge_var.h>
86
87/* tunable params */
88static int mxge_nvidia_ecrc_enable = 1;
89static int mxge_force_firmware = 0;
90static int mxge_intr_coal_delay = 30;
91static int mxge_deassert_wait = 1;
92static int mxge_flow_control = 1;
93static int mxge_verbose = 0;
94static int mxge_lro_cnt = 8;
95static int mxge_ticks;
87#include <dev/mxge/if_mxge_var.h>
88
89/* tunable params */
90static int mxge_nvidia_ecrc_enable = 1;
91static int mxge_force_firmware = 0;
92static int mxge_intr_coal_delay = 30;
93static int mxge_deassert_wait = 1;
94static int mxge_flow_control = 1;
95static int mxge_verbose = 0;
96static int mxge_lro_cnt = 8;
97static int mxge_ticks;
98static int mxge_max_slices = 1;
99static int mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
100static int mxge_always_promisc = 0;
96static char *mxge_fw_unaligned = "mxge_ethp_z8e";
97static char *mxge_fw_aligned = "mxge_eth_z8e";
101static char *mxge_fw_unaligned = "mxge_ethp_z8e";
102static char *mxge_fw_aligned = "mxge_eth_z8e";
103static char *mxge_fw_rss_aligned = "mxge_rss_eth_z8e";
104static char *mxge_fw_rss_unaligned = "mxge_rss_ethp_z8e";
98
99static int mxge_probe(device_t dev);
100static int mxge_attach(device_t dev);
101static int mxge_detach(device_t dev);
102static int mxge_shutdown(device_t dev);
103static void mxge_intr(void *arg);
104
105static device_method_t mxge_methods[] =

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

121
122static devclass_t mxge_devclass;
123
124/* Declare ourselves to be a child of the PCI bus.*/
125DRIVER_MODULE(mxge, pci, mxge_driver, mxge_devclass, 0, 0);
126MODULE_DEPEND(mxge, firmware, 1, 1, 1);
127MODULE_DEPEND(mxge, zlib, 1, 1, 1);
128
105
106static int mxge_probe(device_t dev);
107static int mxge_attach(device_t dev);
108static int mxge_detach(device_t dev);
109static int mxge_shutdown(device_t dev);
110static void mxge_intr(void *arg);
111
112static device_method_t mxge_methods[] =

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

128
129static devclass_t mxge_devclass;
130
131/* Declare ourselves to be a child of the PCI bus.*/
132DRIVER_MODULE(mxge, pci, mxge_driver, mxge_devclass, 0, 0);
133MODULE_DEPEND(mxge, firmware, 1, 1, 1);
134MODULE_DEPEND(mxge, zlib, 1, 1, 1);
135
129static int mxge_load_firmware(mxge_softc_t *sc);
136static int mxge_load_firmware(mxge_softc_t *sc, int adopt);
130static int mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data);
131static int mxge_close(mxge_softc_t *sc);
132static int mxge_open(mxge_softc_t *sc);
133static void mxge_tick(void *arg);
134
135static int
136mxge_probe(device_t dev)
137{

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

190}
191
192static int
193mxge_dma_alloc(mxge_softc_t *sc, mxge_dma_t *dma, size_t bytes,
194 bus_size_t alignment)
195{
196 int err;
197 device_t dev = sc->dev;
137static int mxge_send_cmd(mxge_softc_t *sc, uint32_t cmd, mxge_cmd_t *data);
138static int mxge_close(mxge_softc_t *sc);
139static int mxge_open(mxge_softc_t *sc);
140static void mxge_tick(void *arg);
141
142static int
143mxge_probe(device_t dev)
144{

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

197}
198
199static int
200mxge_dma_alloc(mxge_softc_t *sc, mxge_dma_t *dma, size_t bytes,
201 bus_size_t alignment)
202{
203 int err;
204 device_t dev = sc->dev;
205 bus_size_t boundary, maxsegsize;
198
206
207 if (bytes > 4096 && alignment == 4096) {
208 boundary = 0;
209 maxsegsize = bytes;
210 } else {
211 boundary = 4096;
212 maxsegsize = 4096;
213 }
214
199 /* allocate DMAable memory tags */
200 err = bus_dma_tag_create(sc->parent_dmat, /* parent */
201 alignment, /* alignment */
215 /* allocate DMAable memory tags */
216 err = bus_dma_tag_create(sc->parent_dmat, /* parent */
217 alignment, /* alignment */
202 4096, /* boundary */
218 boundary, /* boundary */
203 BUS_SPACE_MAXADDR, /* low */
204 BUS_SPACE_MAXADDR, /* high */
205 NULL, NULL, /* filter */
206 bytes, /* maxsize */
207 1, /* num segs */
219 BUS_SPACE_MAXADDR, /* low */
220 BUS_SPACE_MAXADDR, /* high */
221 NULL, NULL, /* filter */
222 bytes, /* maxsize */
223 1, /* num segs */
208 4096, /* maxsegsize */
224 maxsegsize, /* maxsegsize */
209 BUS_DMA_COHERENT, /* flags */
210 NULL, NULL, /* lock */
211 &dma->dmat); /* tag */
212 if (err != 0) {
213 device_printf(dev, "couldn't alloc tag (err = %d)\n", err);
214 return err;
215 }
216

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

448 * The magic multipliers to the length tell the firmware
449 * to do DMA read, write, or read+write tests. The
450 * results are returned in cmd.data0. The upper 16
451 * bits of the return is the number of transfers completed.
452 * The lower 16 bits is the time in 0.5us ticks that the
453 * transfers took to complete.
454 */
455
225 BUS_DMA_COHERENT, /* flags */
226 NULL, NULL, /* lock */
227 &dma->dmat); /* tag */
228 if (err != 0) {
229 device_printf(dev, "couldn't alloc tag (err = %d)\n", err);
230 return err;
231 }
232

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

464 * The magic multipliers to the length tell the firmware
465 * to do DMA read, write, or read+write tests. The
466 * results are returned in cmd.data0. The upper 16
467 * bits of the return is the number of transfers completed.
468 * The lower 16 bits is the time in 0.5us ticks that the
469 * transfers took to complete.
470 */
471
456 len = sc->tx.boundary;
472 len = sc->tx_boundary;
457
458 cmd.data0 = MXGE_LOWPART_TO_U32(dmatest_bus);
459 cmd.data1 = MXGE_HIGHPART_TO_U32(dmatest_bus);
460 cmd.data2 = len * 0x10000;
461 status = mxge_send_cmd(sc, test_type, &cmd);
462 if (status != 0) {
463 test = "read";
464 goto abort;

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

504 *
505 * When PCI-E Completion packets are not aligned, it is actually more
506 * efficient to limit Read-DMA transactions to 2KB, rather than 4KB.
507 *
508 * If the driver can neither enable ECRC nor verify that it has
509 * already been enabled, then it must use a firmware image which works
510 * around unaligned completion packets (ethp_z8e.dat), and it should
511 * also ensure that it never gives the device a Read-DMA which is
473
474 cmd.data0 = MXGE_LOWPART_TO_U32(dmatest_bus);
475 cmd.data1 = MXGE_HIGHPART_TO_U32(dmatest_bus);
476 cmd.data2 = len * 0x10000;
477 status = mxge_send_cmd(sc, test_type, &cmd);
478 if (status != 0) {
479 test = "read";
480 goto abort;

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

520 *
521 * When PCI-E Completion packets are not aligned, it is actually more
522 * efficient to limit Read-DMA transactions to 2KB, rather than 4KB.
523 *
524 * If the driver can neither enable ECRC nor verify that it has
525 * already been enabled, then it must use a firmware image which works
526 * around unaligned completion packets (ethp_z8e.dat), and it should
527 * also ensure that it never gives the device a Read-DMA which is
512 * larger than 2KB by setting the tx.boundary to 2KB. If ECRC is
528 * larger than 2KB by setting the tx_boundary to 2KB. If ECRC is
513 * enabled, then the driver should use the aligned (eth_z8e.dat)
529 * enabled, then the driver should use the aligned (eth_z8e.dat)
514 * firmware image, and set tx.boundary to 4KB.
530 * firmware image, and set tx_boundary to 4KB.
515 */
516
517static int
518mxge_firmware_probe(mxge_softc_t *sc)
519{
520 device_t dev = sc->dev;
521 int reg, status;
522 uint16_t pectl;
523
531 */
532
533static int
534mxge_firmware_probe(mxge_softc_t *sc)
535{
536 device_t dev = sc->dev;
537 int reg, status;
538 uint16_t pectl;
539
524 sc->tx.boundary = 4096;
540 sc->tx_boundary = 4096;
525 /*
526 * Verify the max read request size was set to 4KB
527 * before trying the test with 4KB.
528 */
529 if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
530 pectl = pci_read_config(dev, reg + 0x8, 2);
531 if ((pectl & (5 << 12)) != (5 << 12)) {
532 device_printf(dev, "Max Read Req. size != 4k (0x%x\n",
533 pectl);
541 /*
542 * Verify the max read request size was set to 4KB
543 * before trying the test with 4KB.
544 */
545 if (pci_find_extcap(dev, PCIY_EXPRESS, &reg) == 0) {
546 pectl = pci_read_config(dev, reg + 0x8, 2);
547 if ((pectl & (5 << 12)) != (5 << 12)) {
548 device_printf(dev, "Max Read Req. size != 4k (0x%x\n",
549 pectl);
534 sc->tx.boundary = 2048;
550 sc->tx_boundary = 2048;
535 }
536 }
537
538 /*
539 * load the optimized firmware (which assumes aligned PCIe
540 * completions) in order to see if it works on this host.
541 */
542 sc->fw_name = mxge_fw_aligned;
551 }
552 }
553
554 /*
555 * load the optimized firmware (which assumes aligned PCIe
556 * completions) in order to see if it works on this host.
557 */
558 sc->fw_name = mxge_fw_aligned;
543 status = mxge_load_firmware(sc);
559 status = mxge_load_firmware(sc, 1);
544 if (status != 0) {
545 return status;
546 }
547
548 /*
549 * Enable ECRC if possible
550 */
551 mxge_enable_nvidia_ecrc(sc);

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

596 }
597
598 if (0 == mxge_firmware_probe(sc))
599 return 0;
600
601abort:
602 if (aligned) {
603 sc->fw_name = mxge_fw_aligned;
560 if (status != 0) {
561 return status;
562 }
563
564 /*
565 * Enable ECRC if possible
566 */
567 mxge_enable_nvidia_ecrc(sc);

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

612 }
613
614 if (0 == mxge_firmware_probe(sc))
615 return 0;
616
617abort:
618 if (aligned) {
619 sc->fw_name = mxge_fw_aligned;
604 sc->tx.boundary = 4096;
620 sc->tx_boundary = 4096;
605 } else {
606 sc->fw_name = mxge_fw_unaligned;
621 } else {
622 sc->fw_name = mxge_fw_unaligned;
607 sc->tx.boundary = 2048;
623 sc->tx_boundary = 2048;
608 }
624 }
609 return (mxge_load_firmware(sc));
625 return (mxge_load_firmware(sc, 0));
610}
611
612union qualhack
613{
614 const char *ro_char;
615 char *rw_char;
616};
617

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

918 sc->fw_ver_tiny);
919 }
920
921 return status;
922}
923
924
925static int
626}
627
628union qualhack
629{
630 const char *ro_char;
631 char *rw_char;
632};
633

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

934 sc->fw_ver_tiny);
935 }
936
937 return status;
938}
939
940
941static int
926mxge_load_firmware(mxge_softc_t *sc)
942mxge_load_firmware(mxge_softc_t *sc, int adopt)
927{
928 volatile uint32_t *confirm;
929 volatile char *submit;
930 char buf_bytes[72];
931 uint32_t *buf, size, dma_low, dma_high;
932 int status, i;
933
934 buf = (uint32_t *)((unsigned long)(buf_bytes + 7) & ~7UL);
935
936 size = sc->sram_size;
937 status = mxge_load_firmware_helper(sc, &size);
938 if (status) {
943{
944 volatile uint32_t *confirm;
945 volatile char *submit;
946 char buf_bytes[72];
947 uint32_t *buf, size, dma_low, dma_high;
948 int status, i;
949
950 buf = (uint32_t *)((unsigned long)(buf_bytes + 7) & ~7UL);
951
952 size = sc->sram_size;
953 status = mxge_load_firmware_helper(sc, &size);
954 if (status) {
955 if (!adopt)
956 return status;
939 /* Try to use the currently running firmware, if
940 it is new enough */
941 status = mxge_adopt_running_firmware(sc);
942 if (status) {
943 device_printf(sc->dev,
944 "failed to adopt running firmware\n");
945 return status;
946 }
947 device_printf(sc->dev,
948 "Successfully adopted running firmware\n");
957 /* Try to use the currently running firmware, if
958 it is new enough */
959 status = mxge_adopt_running_firmware(sc);
960 if (status) {
961 device_printf(sc->dev,
962 "failed to adopt running firmware\n");
963 return status;
964 }
965 device_printf(sc->dev,
966 "Successfully adopted running firmware\n");
949 if (sc->tx.boundary == 4096) {
967 if (sc->tx_boundary == 4096) {
950 device_printf(sc->dev,
951 "Using firmware currently running on NIC"
952 ". For optimal\n");
953 device_printf(sc->dev,
954 "performance consider loading optimized "
955 "firmware\n");
956 }
957 sc->fw_name = mxge_fw_unaligned;
968 device_printf(sc->dev,
969 "Using firmware currently running on NIC"
970 ". For optimal\n");
971 device_printf(sc->dev,
972 "performance consider loading optimized "
973 "firmware\n");
974 }
975 sc->fw_name = mxge_fw_unaligned;
958 sc->tx.boundary = 2048;
976 sc->tx_boundary = 2048;
959 return 0;
960 }
961 /* clear confirmation addr */
962 confirm = (volatile uint32_t *)sc->cmd;
963 *confirm = 0;
964 mb();
965 /* send a reload command to the bootstrap MCP, and wait for the
966 response in the confirmation address. The firmware should

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

1044}
1045
1046static void
1047mxge_change_promisc(mxge_softc_t *sc, int promisc)
1048{
1049 mxge_cmd_t cmd;
1050 int status;
1051
977 return 0;
978 }
979 /* clear confirmation addr */
980 confirm = (volatile uint32_t *)sc->cmd;
981 *confirm = 0;
982 mb();
983 /* send a reload command to the bootstrap MCP, and wait for the
984 response in the confirmation address. The firmware should

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

1062}
1063
1064static void
1065mxge_change_promisc(mxge_softc_t *sc, int promisc)
1066{
1067 mxge_cmd_t cmd;
1068 int status;
1069
1070 if (mxge_always_promisc)
1071 promisc = 1;
1072
1052 if (promisc)
1053 status = mxge_send_cmd(sc, MXGEFW_ENABLE_PROMISC,
1054 &cmd);
1055 else
1056 status = mxge_send_cmd(sc, MXGEFW_DISABLE_PROMISC,
1057 &cmd);
1058
1059 if (status) {

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

1148
1149 /* otherwise, we're limited to MJUMPAGESIZE */
1150 return MJUMPAGESIZE - MXGEFW_PAD;
1151}
1152
1153static int
1154mxge_reset(mxge_softc_t *sc, int interrupts_setup)
1155{
1073 if (promisc)
1074 status = mxge_send_cmd(sc, MXGEFW_ENABLE_PROMISC,
1075 &cmd);
1076 else
1077 status = mxge_send_cmd(sc, MXGEFW_DISABLE_PROMISC,
1078 &cmd);
1079
1080 if (status) {

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

1169
1170 /* otherwise, we're limited to MJUMPAGESIZE */
1171 return MJUMPAGESIZE - MXGEFW_PAD;
1172}
1173
1174static int
1175mxge_reset(mxge_softc_t *sc, int interrupts_setup)
1176{
1156
1177 struct mxge_slice_state *ss;
1178 mxge_rx_done_t *rx_done;
1179 volatile uint32_t *irq_claim;
1157 mxge_cmd_t cmd;
1180 mxge_cmd_t cmd;
1158 size_t bytes;
1159 int status;
1181 int slice, status;
1160
1161 /* try to send a reset command to the card to see if it
1162 is alive */
1163 memset(&cmd, 0, sizeof (cmd));
1164 status = mxge_send_cmd(sc, MXGEFW_CMD_RESET, &cmd);
1165 if (status != 0) {
1166 device_printf(sc->dev, "failed reset\n");
1167 return ENXIO;
1168 }
1169
1170 mxge_dummy_rdma(sc, 1);
1171
1182
1183 /* try to send a reset command to the card to see if it
1184 is alive */
1185 memset(&cmd, 0, sizeof (cmd));
1186 status = mxge_send_cmd(sc, MXGEFW_CMD_RESET, &cmd);
1187 if (status != 0) {
1188 device_printf(sc->dev, "failed reset\n");
1189 return ENXIO;
1190 }
1191
1192 mxge_dummy_rdma(sc, 1);
1193
1194
1195 /* set the intrq size */
1196 cmd.data0 = sc->rx_ring_size;
1197 status = mxge_send_cmd(sc, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd);
1198
1199 /*
1200 * Even though we already know how many slices are supported
1201 * via mxge_slice_probe(), MXGEFW_CMD_GET_MAX_RSS_QUEUES
1202 * has magic side effects, and must be called after a reset.
1203 * It must be called prior to calling any RSS related cmds,
1204 * including assigning an interrupt queue for anything but
1205 * slice 0. It must also be called *after*
1206 * MXGEFW_CMD_SET_INTRQ_SIZE, since the intrq size is used by
1207 * the firmware to compute offsets.
1208 */
1209
1210 if (sc->num_slices > 1) {
1211 /* ask the maximum number of slices it supports */
1212 status = mxge_send_cmd(sc, MXGEFW_CMD_GET_MAX_RSS_QUEUES,
1213 &cmd);
1214 if (status != 0) {
1215 device_printf(sc->dev,
1216 "failed to get number of slices\n");
1217 return status;
1218 }
1219 /*
1220 * MXGEFW_CMD_ENABLE_RSS_QUEUES must be called prior
1221 * to setting up the interrupt queue DMA
1222 */
1223 cmd.data0 = sc->num_slices;
1224 cmd.data1 = MXGEFW_SLICE_INTR_MODE_ONE_PER_SLICE;
1225 status = mxge_send_cmd(sc, MXGEFW_CMD_ENABLE_RSS_QUEUES,
1226 &cmd);
1227 if (status != 0) {
1228 device_printf(sc->dev,
1229 "failed to set number of slices\n");
1230 return status;
1231 }
1232 }
1233
1234
1172 if (interrupts_setup) {
1173 /* Now exchange information about interrupts */
1235 if (interrupts_setup) {
1236 /* Now exchange information about interrupts */
1174 bytes = (sc->rx_done.mask + 1) * sizeof (*sc->rx_done.entry);
1175 memset(sc->rx_done.entry, 0, bytes);
1176 cmd.data0 = (uint32_t)bytes;
1177 status = mxge_send_cmd(sc, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd);
1178 cmd.data0 = MXGE_LOWPART_TO_U32(sc->rx_done.dma.bus_addr);
1179 cmd.data1 = MXGE_HIGHPART_TO_U32(sc->rx_done.dma.bus_addr);
1180 status |= mxge_send_cmd(sc, MXGEFW_CMD_SET_INTRQ_DMA, &cmd);
1237 for (slice = 0; slice < sc->num_slices; slice++) {
1238 rx_done = &sc->ss[slice].rx_done;
1239 memset(rx_done->entry, 0, sc->rx_ring_size);
1240 cmd.data0 = MXGE_LOWPART_TO_U32(rx_done->dma.bus_addr);
1241 cmd.data1 = MXGE_HIGHPART_TO_U32(rx_done->dma.bus_addr);
1242 cmd.data2 = slice;
1243 status |= mxge_send_cmd(sc,
1244 MXGEFW_CMD_SET_INTRQ_DMA,
1245 &cmd);
1246 }
1181 }
1182
1183 status |= mxge_send_cmd(sc,
1184 MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd);
1185
1186
1187 sc->intr_coal_delay_ptr = (volatile uint32_t *)(sc->sram + cmd.data0);
1188
1189 status |= mxge_send_cmd(sc, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd);
1247 }
1248
1249 status |= mxge_send_cmd(sc,
1250 MXGEFW_CMD_GET_INTR_COAL_DELAY_OFFSET, &cmd);
1251
1252
1253 sc->intr_coal_delay_ptr = (volatile uint32_t *)(sc->sram + cmd.data0);
1254
1255 status |= mxge_send_cmd(sc, MXGEFW_CMD_GET_IRQ_ACK_OFFSET, &cmd);
1190 sc->irq_claim = (volatile uint32_t *)(sc->sram + cmd.data0);
1256 irq_claim = (volatile uint32_t *)(sc->sram + cmd.data0);
1191
1192
1193 status |= mxge_send_cmd(sc, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
1194 &cmd);
1195 sc->irq_deassert = (volatile uint32_t *)(sc->sram + cmd.data0);
1196 if (status != 0) {
1197 device_printf(sc->dev, "failed set interrupt parameters\n");
1198 return status;
1199 }
1200
1201
1202 *sc->intr_coal_delay_ptr = htobe32(sc->intr_coal_delay);
1203
1204
1205 /* run a DMA benchmark */
1206 (void) mxge_dma_test(sc, MXGEFW_DMA_TEST);
1207
1257
1258
1259 status |= mxge_send_cmd(sc, MXGEFW_CMD_GET_IRQ_DEASSERT_OFFSET,
1260 &cmd);
1261 sc->irq_deassert = (volatile uint32_t *)(sc->sram + cmd.data0);
1262 if (status != 0) {
1263 device_printf(sc->dev, "failed set interrupt parameters\n");
1264 return status;
1265 }
1266
1267
1268 *sc->intr_coal_delay_ptr = htobe32(sc->intr_coal_delay);
1269
1270
1271 /* run a DMA benchmark */
1272 (void) mxge_dma_test(sc, MXGEFW_DMA_TEST);
1273
1208 /* reset mcp/driver shared state back to 0 */
1209 sc->rx_done.idx = 0;
1210 sc->rx_done.cnt = 0;
1211 sc->tx.req = 0;
1212 sc->tx.done = 0;
1213 sc->tx.pkt_done = 0;
1214 sc->tx.wake = 0;
1215 sc->tx_defrag = 0;
1216 sc->tx.stall = 0;
1217 sc->rx_big.cnt = 0;
1218 sc->rx_small.cnt = 0;
1274 for (slice = 0; slice < sc->num_slices; slice++) {
1275 ss = &sc->ss[slice];
1276
1277 ss->irq_claim = irq_claim + (2 * slice);
1278 /* reset mcp/driver shared state back to 0 */
1279 ss->rx_done.idx = 0;
1280 ss->rx_done.cnt = 0;
1281 ss->tx.req = 0;
1282 ss->tx.done = 0;
1283 ss->tx.pkt_done = 0;
1284 ss->tx.wake = 0;
1285 ss->tx.defrag = 0;
1286 ss->tx.stall = 0;
1287 ss->rx_big.cnt = 0;
1288 ss->rx_small.cnt = 0;
1289 ss->lro_bad_csum = 0;
1290 ss->lro_queued = 0;
1291 ss->lro_flushed = 0;
1292 if (ss->fw_stats != NULL) {
1293 ss->fw_stats->valid = 0;
1294 ss->fw_stats->send_done_count = 0;
1295 }
1296 }
1219 sc->rdma_tags_available = 15;
1297 sc->rdma_tags_available = 15;
1220 sc->fw_stats->valid = 0;
1221 sc->fw_stats->send_done_count = 0;
1222 sc->lro_bad_csum = 0;
1223 sc->lro_queued = 0;
1224 sc->lro_flushed = 0;
1225 status = mxge_update_mac_address(sc);
1226 mxge_change_promisc(sc, 0);
1227 mxge_change_pause(sc, sc->pause);
1228 mxge_set_multicast_list(sc);
1229 return status;
1230}
1231
1232static int

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

1335 arg2 = be32toh(*(int *)arg1);
1336 arg1 = NULL;
1337 err = sysctl_handle_int(oidp, arg1, arg2, req);
1338
1339 return err;
1340}
1341
1342static void
1298 status = mxge_update_mac_address(sc);
1299 mxge_change_promisc(sc, 0);
1300 mxge_change_pause(sc, sc->pause);
1301 mxge_set_multicast_list(sc);
1302 return status;
1303}
1304
1305static int

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

1408 arg2 = be32toh(*(int *)arg1);
1409 arg1 = NULL;
1410 err = sysctl_handle_int(oidp, arg1, arg2, req);
1411
1412 return err;
1413}
1414
1415static void
1416mxge_rem_sysctls(mxge_softc_t *sc)
1417{
1418 struct mxge_slice_state *ss;
1419 int slice;
1420
1421 if (sc->slice_sysctl_tree == NULL)
1422 return;
1423
1424 for (slice = 0; slice < sc->num_slices; slice++) {
1425 ss = &sc->ss[slice];
1426 if (ss == NULL || ss->sysctl_tree == NULL)
1427 continue;
1428 sysctl_ctx_free(&ss->sysctl_ctx);
1429 ss->sysctl_tree = NULL;
1430 }
1431 sysctl_ctx_free(&sc->slice_sysctl_ctx);
1432 sc->slice_sysctl_tree = NULL;
1433}
1434
1435static void
1343mxge_add_sysctls(mxge_softc_t *sc)
1344{
1345 struct sysctl_ctx_list *ctx;
1346 struct sysctl_oid_list *children;
1347 mcp_irq_data_t *fw;
1436mxge_add_sysctls(mxge_softc_t *sc)
1437{
1438 struct sysctl_ctx_list *ctx;
1439 struct sysctl_oid_list *children;
1440 mcp_irq_data_t *fw;
1441 struct mxge_slice_state *ss;
1442 int slice;
1443 char slice_num[8];
1348
1349 ctx = device_get_sysctl_ctx(sc->dev);
1350 children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
1444
1445 ctx = device_get_sysctl_ctx(sc->dev);
1446 children = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->dev));
1351 fw = sc->fw_stats;
1447 fw = sc->ss[0].fw_stats;
1352
1353 /* random information */
1354 SYSCTL_ADD_STRING(ctx, children, OID_AUTO,
1355 "firmware_version",
1356 CTLFLAG_RD, &sc->fw_version,
1357 0, "firmware version");
1358 SYSCTL_ADD_STRING(ctx, children, OID_AUTO,
1359 "serial_number",

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

1364 CTLFLAG_RD, &sc->product_code_string,
1365 0, "product_code");
1366 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1367 "pcie_link_width",
1368 CTLFLAG_RD, &sc->link_width,
1369 0, "tx_boundary");
1370 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1371 "tx_boundary",
1448
1449 /* random information */
1450 SYSCTL_ADD_STRING(ctx, children, OID_AUTO,
1451 "firmware_version",
1452 CTLFLAG_RD, &sc->fw_version,
1453 0, "firmware version");
1454 SYSCTL_ADD_STRING(ctx, children, OID_AUTO,
1455 "serial_number",

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

1460 CTLFLAG_RD, &sc->product_code_string,
1461 0, "product_code");
1462 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1463 "pcie_link_width",
1464 CTLFLAG_RD, &sc->link_width,
1465 0, "tx_boundary");
1466 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1467 "tx_boundary",
1372 CTLFLAG_RD, &sc->tx.boundary,
1468 CTLFLAG_RD, &sc->tx_boundary,
1373 0, "tx_boundary");
1374 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1375 "write_combine",
1376 CTLFLAG_RD, &sc->wc,
1377 0, "write combining PIO?");
1378 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1379 "read_dma_MBs",
1380 CTLFLAG_RD, &sc->read_dma,

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

1477 "I", "dropped_runt");
1478
1479 SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
1480 "dropped_unicast_filtered",
1481 CTLTYPE_INT|CTLFLAG_RD, &fw->dropped_unicast_filtered,
1482 0, mxge_handle_be32,
1483 "I", "dropped_unicast_filtered");
1484
1469 0, "tx_boundary");
1470 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1471 "write_combine",
1472 CTLFLAG_RD, &sc->wc,
1473 0, "write combining PIO?");
1474 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1475 "read_dma_MBs",
1476 CTLFLAG_RD, &sc->read_dma,

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

1573 "I", "dropped_runt");
1574
1575 SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
1576 "dropped_unicast_filtered",
1577 CTLTYPE_INT|CTLFLAG_RD, &fw->dropped_unicast_filtered,
1578 0, mxge_handle_be32,
1579 "I", "dropped_unicast_filtered");
1580
1485 /* host counters exported for debugging */
1486 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1487 "rx_small_cnt",
1488 CTLFLAG_RD, &sc->rx_small.cnt,
1489 0, "rx_small_cnt");
1490 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1491 "rx_big_cnt",
1492 CTLFLAG_RD, &sc->rx_big.cnt,
1493 0, "rx_small_cnt");
1494 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1495 "tx_req",
1496 CTLFLAG_RD, &sc->tx.req,
1497 0, "tx_req");
1498 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1499 "tx_done",
1500 CTLFLAG_RD, &sc->tx.done,
1501 0, "tx_done");
1502 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1503 "tx_pkt_done",
1504 CTLFLAG_RD, &sc->tx.pkt_done,
1505 0, "tx_done");
1506 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1507 "tx_stall",
1508 CTLFLAG_RD, &sc->tx.stall,
1509 0, "tx_stall");
1510 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1511 "tx_wake",
1512 CTLFLAG_RD, &sc->tx.wake,
1513 0, "tx_wake");
1514 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1515 "tx_defrag",
1516 CTLFLAG_RD, &sc->tx_defrag,
1517 0, "tx_defrag");
1518
1519 /* verbose printing? */
1520 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1521 "verbose",
1522 CTLFLAG_RW, &mxge_verbose,
1523 0, "verbose printing");
1524
1525 /* lro */
1526 SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
1527 "lro_cnt",
1528 CTLTYPE_INT|CTLFLAG_RW, sc,
1529 0, mxge_change_lro,
1530 "I", "number of lro merge queues");
1531
1581 /* verbose printing? */
1582 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1583 "verbose",
1584 CTLFLAG_RW, &mxge_verbose,
1585 0, "verbose printing");
1586
1587 /* lro */
1588 SYSCTL_ADD_PROC(ctx, children, OID_AUTO,
1589 "lro_cnt",
1590 CTLTYPE_INT|CTLFLAG_RW, sc,
1591 0, mxge_change_lro,
1592 "I", "number of lro merge queues");
1593
1532 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1533 "lro_flushed", CTLFLAG_RD, &sc->lro_flushed,
1534 0, "number of lro merge queues flushed");
1535
1594
1536 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1537 "lro_queued", CTLFLAG_RD, &sc->lro_queued,
1538 0, "number of frames appended to lro merge queues");
1595 /* add counters exported for debugging from all slices */
1596 sysctl_ctx_init(&sc->slice_sysctl_ctx);
1597 sc->slice_sysctl_tree =
1598 SYSCTL_ADD_NODE(&sc->slice_sysctl_ctx, children, OID_AUTO,
1599 "slice", CTLFLAG_RD, 0, "");
1539
1600
1601 for (slice = 0; slice < sc->num_slices; slice++) {
1602 ss = &sc->ss[slice];
1603 sysctl_ctx_init(&ss->sysctl_ctx);
1604 ctx = &ss->sysctl_ctx;
1605 children = SYSCTL_CHILDREN(sc->slice_sysctl_tree);
1606 sprintf(slice_num, "%d", slice);
1607 ss->sysctl_tree =
1608 SYSCTL_ADD_NODE(ctx, children, OID_AUTO, slice_num,
1609 CTLFLAG_RD, 0, "");
1610 children = SYSCTL_CHILDREN(ss->sysctl_tree);
1611 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1612 "rx_small_cnt",
1613 CTLFLAG_RD, &ss->rx_small.cnt,
1614 0, "rx_small_cnt");
1615 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1616 "rx_big_cnt",
1617 CTLFLAG_RD, &ss->rx_big.cnt,
1618 0, "rx_small_cnt");
1619 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1620 "tx_req",
1621 CTLFLAG_RD, &ss->tx.req,
1622 0, "tx_req");
1623 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1624 "lro_flushed", CTLFLAG_RD, &ss->lro_flushed,
1625 0, "number of lro merge queues flushed");
1626
1627 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1628 "lro_queued", CTLFLAG_RD, &ss->lro_queued,
1629 0, "number of frames appended to lro merge"
1630 "queues");
1631
1632 /* only transmit from slice 0 for now */
1633 if (slice > 0)
1634 continue;
1635
1636 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1637 "tx_done",
1638 CTLFLAG_RD, &ss->tx.done,
1639 0, "tx_done");
1640 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1641 "tx_pkt_done",
1642 CTLFLAG_RD, &ss->tx.pkt_done,
1643 0, "tx_done");
1644 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1645 "tx_stall",
1646 CTLFLAG_RD, &ss->tx.stall,
1647 0, "tx_stall");
1648 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1649 "tx_wake",
1650 CTLFLAG_RD, &ss->tx.wake,
1651 0, "tx_wake");
1652 SYSCTL_ADD_INT(ctx, children, OID_AUTO,
1653 "tx_defrag",
1654 CTLFLAG_RD, &ss->tx.defrag,
1655 0, "tx_defrag");
1656 }
1540}
1541
1542/* copy an array of mcp_kreq_ether_send_t's to the mcp. Copy
1543 backwards one at a time and handle ring wraps */
1544
1545static inline void
1657}
1658
1659/* copy an array of mcp_kreq_ether_send_t's to the mcp. Copy
1660 backwards one at a time and handle ring wraps */
1661
1662static inline void
1546mxge_submit_req_backwards(mxge_tx_buf_t *tx,
1663mxge_submit_req_backwards(mxge_tx_ring_t *tx,
1547 mcp_kreq_ether_send_t *src, int cnt)
1548{
1549 int idx, starting_slot;
1550 starting_slot = tx->req;
1551 while (cnt > 1) {
1552 cnt--;
1553 idx = (starting_slot + cnt) & tx->mask;
1554 mxge_pio_copy(&tx->lanai[idx],

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

1560/*
1561 * copy an array of mcp_kreq_ether_send_t's to the mcp. Copy
1562 * at most 32 bytes at a time, so as to avoid involving the software
1563 * pio handler in the nic. We re-write the first segment's flags
1564 * to mark them valid only after writing the entire chain
1565 */
1566
1567static inline void
1664 mcp_kreq_ether_send_t *src, int cnt)
1665{
1666 int idx, starting_slot;
1667 starting_slot = tx->req;
1668 while (cnt > 1) {
1669 cnt--;
1670 idx = (starting_slot + cnt) & tx->mask;
1671 mxge_pio_copy(&tx->lanai[idx],

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

1677/*
1678 * copy an array of mcp_kreq_ether_send_t's to the mcp. Copy
1679 * at most 32 bytes at a time, so as to avoid involving the software
1680 * pio handler in the nic. We re-write the first segment's flags
1681 * to mark them valid only after writing the entire chain
1682 */
1683
1684static inline void
1568mxge_submit_req(mxge_tx_buf_t *tx, mcp_kreq_ether_send_t *src,
1685mxge_submit_req(mxge_tx_ring_t *tx, mcp_kreq_ether_send_t *src,
1569 int cnt)
1570{
1571 int idx, i;
1572 uint32_t *src_ints;
1573 volatile uint32_t *dst_ints;
1574 mcp_kreq_ether_send_t *srcp;
1575 volatile mcp_kreq_ether_send_t *dstp, *dst;
1576 uint8_t last_flags;

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

1609 dst_ints = (volatile uint32_t *)dst;
1610 dst_ints+=3;
1611 *dst_ints = *src_ints;
1612 tx->req += cnt;
1613 mb();
1614}
1615
1616static void
1686 int cnt)
1687{
1688 int idx, i;
1689 uint32_t *src_ints;
1690 volatile uint32_t *dst_ints;
1691 mcp_kreq_ether_send_t *srcp;
1692 volatile mcp_kreq_ether_send_t *dstp, *dst;
1693 uint8_t last_flags;

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

1726 dst_ints = (volatile uint32_t *)dst;
1727 dst_ints+=3;
1728 *dst_ints = *src_ints;
1729 tx->req += cnt;
1730 mb();
1731}
1732
1733static void
1617mxge_encap_tso(mxge_softc_t *sc, struct mbuf *m, int busdma_seg_cnt,
1618 int ip_off)
1734mxge_encap_tso(struct mxge_slice_state *ss, struct mbuf *m,
1735 int busdma_seg_cnt, int ip_off)
1619{
1736{
1620 mxge_tx_buf_t *tx;
1737 mxge_tx_ring_t *tx;
1621 mcp_kreq_ether_send_t *req;
1622 bus_dma_segment_t *seg;
1623 struct ip *ip;
1624 struct tcphdr *tcp;
1625 uint32_t low, high_swapped;
1626 int len, seglen, cum_len, cum_len_next;
1627 int next_is_first, chop, cnt, rdma_count, small;
1628 uint16_t pseudo_hdr_offset, cksum_offset, mss;
1629 uint8_t flags, flags_next;
1630 static int once;
1738 mcp_kreq_ether_send_t *req;
1739 bus_dma_segment_t *seg;
1740 struct ip *ip;
1741 struct tcphdr *tcp;
1742 uint32_t low, high_swapped;
1743 int len, seglen, cum_len, cum_len_next;
1744 int next_is_first, chop, cnt, rdma_count, small;
1745 uint16_t pseudo_hdr_offset, cksum_offset, mss;
1746 uint8_t flags, flags_next;
1747 static int once;
1631
1748
1632 mss = m->m_pkthdr.tso_segsz;
1633
1634 /* negative cum_len signifies to the
1635 * send loop that we are still in the
1636 * header portion of the TSO packet.
1637 */
1638
1639 /* ensure we have the ethernet, IP and TCP
1640 header together in the first mbuf, copy
1641 it to a scratch buffer if not */
1642 if (__predict_false(m->m_len < ip_off + sizeof (*ip))) {
1643 m_copydata(m, 0, ip_off + sizeof (*ip),
1749 mss = m->m_pkthdr.tso_segsz;
1750
1751 /* negative cum_len signifies to the
1752 * send loop that we are still in the
1753 * header portion of the TSO packet.
1754 */
1755
1756 /* ensure we have the ethernet, IP and TCP
1757 header together in the first mbuf, copy
1758 it to a scratch buffer if not */
1759 if (__predict_false(m->m_len < ip_off + sizeof (*ip))) {
1760 m_copydata(m, 0, ip_off + sizeof (*ip),
1644 sc->scratch);
1645 ip = (struct ip *)(sc->scratch + ip_off);
1761 ss->scratch);
1762 ip = (struct ip *)(ss->scratch + ip_off);
1646 } else {
1647 ip = (struct ip *)(mtod(m, char *) + ip_off);
1648 }
1649 if (__predict_false(m->m_len < ip_off + (ip->ip_hl << 2)
1650 + sizeof (*tcp))) {
1651 m_copydata(m, 0, ip_off + (ip->ip_hl << 2)
1763 } else {
1764 ip = (struct ip *)(mtod(m, char *) + ip_off);
1765 }
1766 if (__predict_false(m->m_len < ip_off + (ip->ip_hl << 2)
1767 + sizeof (*tcp))) {
1768 m_copydata(m, 0, ip_off + (ip->ip_hl << 2)
1652 + sizeof (*tcp), sc->scratch);
1769 + sizeof (*tcp), ss->scratch);
1653 ip = (struct ip *)(mtod(m, char *) + ip_off);
1654 }
1655
1656 tcp = (struct tcphdr *)((char *)ip + (ip->ip_hl << 2));
1657 cum_len = -(ip_off + ((ip->ip_hl + tcp->th_off) << 2));
1658
1659 /* TSO implies checksum offload on this hardware */
1660 cksum_offset = ip_off + (ip->ip_hl << 2);
1661 flags = MXGEFW_FLAGS_TSO_HDR | MXGEFW_FLAGS_FIRST;
1662
1663
1664 /* for TSO, pseudo_hdr_offset holds mss.
1665 * The firmware figures out where to put
1666 * the checksum by parsing the header. */
1667 pseudo_hdr_offset = htobe16(mss);
1668
1770 ip = (struct ip *)(mtod(m, char *) + ip_off);
1771 }
1772
1773 tcp = (struct tcphdr *)((char *)ip + (ip->ip_hl << 2));
1774 cum_len = -(ip_off + ((ip->ip_hl + tcp->th_off) << 2));
1775
1776 /* TSO implies checksum offload on this hardware */
1777 cksum_offset = ip_off + (ip->ip_hl << 2);
1778 flags = MXGEFW_FLAGS_TSO_HDR | MXGEFW_FLAGS_FIRST;
1779
1780
1781 /* for TSO, pseudo_hdr_offset holds mss.
1782 * The firmware figures out where to put
1783 * the checksum by parsing the header. */
1784 pseudo_hdr_offset = htobe16(mss);
1785
1669 tx = &sc->tx;
1786 tx = &ss->tx;
1670 req = tx->req_list;
1671 seg = tx->seg_list;
1672 cnt = 0;
1673 rdma_count = 0;
1674 /* "rdma_count" is the number of RDMAs belonging to the
1675 * current packet BEFORE the current send request. For
1676 * non-TSO packets, this is equal to "count".
1677 * For TSO packets, rdma_count needs to be reset

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

1756
1757 tx->info[((cnt - 1) + tx->req) & tx->mask].flag = 1;
1758 mxge_submit_req(tx, tx->req_list, cnt);
1759 return;
1760
1761drop:
1762 bus_dmamap_unload(tx->dmat, tx->info[tx->req & tx->mask].map);
1763 m_freem(m);
1787 req = tx->req_list;
1788 seg = tx->seg_list;
1789 cnt = 0;
1790 rdma_count = 0;
1791 /* "rdma_count" is the number of RDMAs belonging to the
1792 * current packet BEFORE the current send request. For
1793 * non-TSO packets, this is equal to "count".
1794 * For TSO packets, rdma_count needs to be reset

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

1873
1874 tx->info[((cnt - 1) + tx->req) & tx->mask].flag = 1;
1875 mxge_submit_req(tx, tx->req_list, cnt);
1876 return;
1877
1878drop:
1879 bus_dmamap_unload(tx->dmat, tx->info[tx->req & tx->mask].map);
1880 m_freem(m);
1764 sc->ifp->if_oerrors++;
1881 ss->sc->ifp->if_oerrors++;
1765 if (!once) {
1766 printf("tx->max_desc exceeded via TSO!\n");
1767 printf("mss = %d, %ld, %d!\n", mss,
1768 (long)seg - (long)tx->seg_list, tx->max_desc);
1769 once = 1;
1770 }
1771 return;
1772

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

1800 (char *)evl, ETHER_HDR_LEN - ETHER_TYPE_LEN);
1801 evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
1802 evl->evl_tag = htons(m->m_pkthdr.ether_vtag);
1803 m->m_flags &= ~M_VLANTAG;
1804 return m;
1805}
1806
1807static void
1882 if (!once) {
1883 printf("tx->max_desc exceeded via TSO!\n");
1884 printf("mss = %d, %ld, %d!\n", mss,
1885 (long)seg - (long)tx->seg_list, tx->max_desc);
1886 once = 1;
1887 }
1888 return;
1889

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

1917 (char *)evl, ETHER_HDR_LEN - ETHER_TYPE_LEN);
1918 evl->evl_encap_proto = htons(ETHERTYPE_VLAN);
1919 evl->evl_tag = htons(m->m_pkthdr.ether_vtag);
1920 m->m_flags &= ~M_VLANTAG;
1921 return m;
1922}
1923
1924static void
1808mxge_encap(mxge_softc_t *sc, struct mbuf *m)
1925mxge_encap(struct mxge_slice_state *ss, struct mbuf *m)
1809{
1926{
1927 mxge_softc_t *sc;
1810 mcp_kreq_ether_send_t *req;
1811 bus_dma_segment_t *seg;
1812 struct mbuf *m_tmp;
1813 struct ifnet *ifp;
1928 mcp_kreq_ether_send_t *req;
1929 bus_dma_segment_t *seg;
1930 struct mbuf *m_tmp;
1931 struct ifnet *ifp;
1814 mxge_tx_buf_t *tx;
1932 mxge_tx_ring_t *tx;
1815 struct ip *ip;
1816 int cnt, cum_len, err, i, idx, odd_flag, ip_off;
1817 uint16_t pseudo_hdr_offset;
1818 uint8_t flags, cksum_offset;
1819
1820
1933 struct ip *ip;
1934 int cnt, cum_len, err, i, idx, odd_flag, ip_off;
1935 uint16_t pseudo_hdr_offset;
1936 uint8_t flags, cksum_offset;
1937
1938
1821
1939 sc = ss->sc;
1822 ifp = sc->ifp;
1940 ifp = sc->ifp;
1823 tx = &sc->tx;
1941 tx = &ss->tx;
1824
1825 ip_off = sizeof (struct ether_header);
1826 if (m->m_flags & M_VLANTAG) {
1827 m = mxge_vlan_tag_insert(m);
1828 if (__predict_false(m == NULL))
1829 goto drop;
1830 ip_off += ETHER_VLAN_ENCAP_LEN;
1831 }

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

1837 BUS_DMA_NOWAIT);
1838 if (__predict_false(err == EFBIG)) {
1839 /* Too many segments in the chain. Try
1840 to defrag */
1841 m_tmp = m_defrag(m, M_NOWAIT);
1842 if (m_tmp == NULL) {
1843 goto drop;
1844 }
1942
1943 ip_off = sizeof (struct ether_header);
1944 if (m->m_flags & M_VLANTAG) {
1945 m = mxge_vlan_tag_insert(m);
1946 if (__predict_false(m == NULL))
1947 goto drop;
1948 ip_off += ETHER_VLAN_ENCAP_LEN;
1949 }

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

1955 BUS_DMA_NOWAIT);
1956 if (__predict_false(err == EFBIG)) {
1957 /* Too many segments in the chain. Try
1958 to defrag */
1959 m_tmp = m_defrag(m, M_NOWAIT);
1960 if (m_tmp == NULL) {
1961 goto drop;
1962 }
1845 sc->tx_defrag++;
1963 ss->tx.defrag++;
1846 m = m_tmp;
1847 err = bus_dmamap_load_mbuf_sg(tx->dmat,
1848 tx->info[idx].map,
1849 m, tx->seg_list, &cnt,
1850 BUS_DMA_NOWAIT);
1851 }
1852 if (__predict_false(err != 0)) {
1853 device_printf(sc->dev, "bus_dmamap_load_mbuf_sg returned %d"
1854 " packet len = %d\n", err, m->m_pkthdr.len);
1855 goto drop;
1856 }
1857 bus_dmamap_sync(tx->dmat, tx->info[idx].map,
1858 BUS_DMASYNC_PREWRITE);
1859 tx->info[idx].m = m;
1860
1861
1862 /* TSO is different enough, we handle it in another routine */
1863 if (m->m_pkthdr.csum_flags & (CSUM_TSO)) {
1964 m = m_tmp;
1965 err = bus_dmamap_load_mbuf_sg(tx->dmat,
1966 tx->info[idx].map,
1967 m, tx->seg_list, &cnt,
1968 BUS_DMA_NOWAIT);
1969 }
1970 if (__predict_false(err != 0)) {
1971 device_printf(sc->dev, "bus_dmamap_load_mbuf_sg returned %d"
1972 " packet len = %d\n", err, m->m_pkthdr.len);
1973 goto drop;
1974 }
1975 bus_dmamap_sync(tx->dmat, tx->info[idx].map,
1976 BUS_DMASYNC_PREWRITE);
1977 tx->info[idx].m = m;
1978
1979
1980 /* TSO is different enough, we handle it in another routine */
1981 if (m->m_pkthdr.csum_flags & (CSUM_TSO)) {
1864 mxge_encap_tso(sc, m, cnt, ip_off);
1982 mxge_encap_tso(ss, m, cnt, ip_off);
1865 return;
1866 }
1867
1868 req = tx->req_list;
1869 cksum_offset = 0;
1870 pseudo_hdr_offset = 0;
1871 flags = MXGEFW_FLAGS_NO_TSO;
1872
1873 /* checksum offloading? */
1874 if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA)) {
1875 /* ensure ip header is in first mbuf, copy
1876 it to a scratch buffer if not */
1877 if (__predict_false(m->m_len < ip_off + sizeof (*ip))) {
1878 m_copydata(m, 0, ip_off + sizeof (*ip),
1983 return;
1984 }
1985
1986 req = tx->req_list;
1987 cksum_offset = 0;
1988 pseudo_hdr_offset = 0;
1989 flags = MXGEFW_FLAGS_NO_TSO;
1990
1991 /* checksum offloading? */
1992 if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA)) {
1993 /* ensure ip header is in first mbuf, copy
1994 it to a scratch buffer if not */
1995 if (__predict_false(m->m_len < ip_off + sizeof (*ip))) {
1996 m_copydata(m, 0, ip_off + sizeof (*ip),
1879 sc->scratch);
1880 ip = (struct ip *)(sc->scratch + ip_off);
1997 ss->scratch);
1998 ip = (struct ip *)(ss->scratch + ip_off);
1881 } else {
1882 ip = (struct ip *)(mtod(m, char *) + ip_off);
1883 }
1884 cksum_offset = ip_off + (ip->ip_hl << 2);
1885 pseudo_hdr_offset = cksum_offset + m->m_pkthdr.csum_data;
1886 pseudo_hdr_offset = htobe16(pseudo_hdr_offset);
1887 req->cksum_offset = cksum_offset;
1888 flags |= MXGEFW_FLAGS_CKSUM;

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

1958 ifp->if_oerrors++;
1959 return;
1960}
1961
1962
1963
1964
1965static inline void
1999 } else {
2000 ip = (struct ip *)(mtod(m, char *) + ip_off);
2001 }
2002 cksum_offset = ip_off + (ip->ip_hl << 2);
2003 pseudo_hdr_offset = cksum_offset + m->m_pkthdr.csum_data;
2004 pseudo_hdr_offset = htobe16(pseudo_hdr_offset);
2005 req->cksum_offset = cksum_offset;
2006 flags |= MXGEFW_FLAGS_CKSUM;

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

2076 ifp->if_oerrors++;
2077 return;
2078}
2079
2080
2081
2082
2083static inline void
1966mxge_start_locked(mxge_softc_t *sc)
2084mxge_start_locked(struct mxge_slice_state *ss)
1967{
2085{
2086 mxge_softc_t *sc;
1968 struct mbuf *m;
1969 struct ifnet *ifp;
2087 struct mbuf *m;
2088 struct ifnet *ifp;
1970 mxge_tx_buf_t *tx;
2089 mxge_tx_ring_t *tx;
1971
2090
2091 sc = ss->sc;
1972 ifp = sc->ifp;
2092 ifp = sc->ifp;
1973 tx = &sc->tx;
2093 tx = &ss->tx;
1974 while ((tx->mask - (tx->req - tx->done)) > tx->max_desc) {
1975 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
1976 if (m == NULL) {
1977 return;
1978 }
1979 /* let BPF see it */
1980 BPF_MTAP(ifp, m);
1981
1982 /* give it to the nic */
2094 while ((tx->mask - (tx->req - tx->done)) > tx->max_desc) {
2095 IFQ_DRV_DEQUEUE(&ifp->if_snd, m);
2096 if (m == NULL) {
2097 return;
2098 }
2099 /* let BPF see it */
2100 BPF_MTAP(ifp, m);
2101
2102 /* give it to the nic */
1983 mxge_encap(sc, m);
2103 mxge_encap(ss, m);
1984 }
1985 /* ran out of transmit slots */
1986 if ((sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
1987 sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE;
1988 tx->stall++;
1989 }
1990}
1991
1992static void
1993mxge_start(struct ifnet *ifp)
1994{
1995 mxge_softc_t *sc = ifp->if_softc;
2104 }
2105 /* ran out of transmit slots */
2106 if ((sc->ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0) {
2107 sc->ifp->if_drv_flags |= IFF_DRV_OACTIVE;
2108 tx->stall++;
2109 }
2110}
2111
2112static void
2113mxge_start(struct ifnet *ifp)
2114{
2115 mxge_softc_t *sc = ifp->if_softc;
2116 struct mxge_slice_state *ss;
1996
2117
1997
1998 mtx_lock(&sc->tx_mtx);
1999 mxge_start_locked(sc);
2000 mtx_unlock(&sc->tx_mtx);
2118 /* only use the first slice for now */
2119 ss = &sc->ss[0];
2120 mtx_lock(&ss->tx.mtx);
2121 mxge_start_locked(ss);
2122 mtx_unlock(&ss->tx.mtx);
2001}
2002
2003/*
2004 * copy an array of mcp_kreq_ether_recv_t's to the mcp. Copy
2005 * at most 32 bytes at a time, so as to avoid involving the software
2006 * pio handler in the nic. We re-write the first segment's low
2007 * DMA address to mark it valid only after we write the entire chunk
2008 * in a burst

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

2020 mxge_pio_copy(dst + 4, src + 4, 4 * sizeof (*src));
2021 mb();
2022 src->addr_low = low;
2023 dst->addr_low = low;
2024 mb();
2025}
2026
2027static int
2123}
2124
2125/*
2126 * copy an array of mcp_kreq_ether_recv_t's to the mcp. Copy
2127 * at most 32 bytes at a time, so as to avoid involving the software
2128 * pio handler in the nic. We re-write the first segment's low
2129 * DMA address to mark it valid only after we write the entire chunk
2130 * in a burst

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

2142 mxge_pio_copy(dst + 4, src + 4, 4 * sizeof (*src));
2143 mb();
2144 src->addr_low = low;
2145 dst->addr_low = low;
2146 mb();
2147}
2148
2149static int
2028mxge_get_buf_small(mxge_softc_t *sc, bus_dmamap_t map, int idx)
2150mxge_get_buf_small(struct mxge_slice_state *ss, bus_dmamap_t map, int idx)
2029{
2030 bus_dma_segment_t seg;
2031 struct mbuf *m;
2151{
2152 bus_dma_segment_t seg;
2153 struct mbuf *m;
2032 mxge_rx_buf_t *rx = &sc->rx_small;
2154 mxge_rx_ring_t *rx = &ss->rx_small;
2033 int cnt, err;
2034
2035 m = m_gethdr(M_DONTWAIT, MT_DATA);
2036 if (m == NULL) {
2037 rx->alloc_fail++;
2038 err = ENOBUFS;
2039 goto done;
2040 }

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

2053
2054done:
2055 if ((idx & 7) == 7)
2056 mxge_submit_8rx(&rx->lanai[idx - 7], &rx->shadow[idx - 7]);
2057 return err;
2058}
2059
2060static int
2155 int cnt, err;
2156
2157 m = m_gethdr(M_DONTWAIT, MT_DATA);
2158 if (m == NULL) {
2159 rx->alloc_fail++;
2160 err = ENOBUFS;
2161 goto done;
2162 }

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

2175
2176done:
2177 if ((idx & 7) == 7)
2178 mxge_submit_8rx(&rx->lanai[idx - 7], &rx->shadow[idx - 7]);
2179 return err;
2180}
2181
2182static int
2061mxge_get_buf_big(mxge_softc_t *sc, bus_dmamap_t map, int idx)
2183mxge_get_buf_big(struct mxge_slice_state *ss, bus_dmamap_t map, int idx)
2062{
2063 bus_dma_segment_t seg[3];
2064 struct mbuf *m;
2184{
2185 bus_dma_segment_t seg[3];
2186 struct mbuf *m;
2065 mxge_rx_buf_t *rx = &sc->rx_big;
2187 mxge_rx_ring_t *rx = &ss->rx_big;
2066 int cnt, err, i;
2067
2068 if (rx->cl_size == MCLBYTES)
2069 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
2070 else
2071 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, rx->cl_size);
2072 if (m == NULL) {
2073 rx->alloc_fail++;

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

2175 */
2176 bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,
2177 ETHER_HDR_LEN - ETHER_TYPE_LEN);
2178 m_adj(m, ETHER_VLAN_ENCAP_LEN);
2179}
2180
2181
2182static inline void
2188 int cnt, err, i;
2189
2190 if (rx->cl_size == MCLBYTES)
2191 m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
2192 else
2193 m = m_getjcl(M_DONTWAIT, MT_DATA, M_PKTHDR, rx->cl_size);
2194 if (m == NULL) {
2195 rx->alloc_fail++;

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

2297 */
2298 bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,
2299 ETHER_HDR_LEN - ETHER_TYPE_LEN);
2300 m_adj(m, ETHER_VLAN_ENCAP_LEN);
2301}
2302
2303
2304static inline void
2183mxge_rx_done_big(mxge_softc_t *sc, uint32_t len, uint32_t csum)
2305mxge_rx_done_big(struct mxge_slice_state *ss, uint32_t len, uint32_t csum)
2184{
2306{
2307 mxge_softc_t *sc;
2185 struct ifnet *ifp;
2186 struct mbuf *m;
2187 struct ether_header *eh;
2308 struct ifnet *ifp;
2309 struct mbuf *m;
2310 struct ether_header *eh;
2188 mxge_rx_buf_t *rx;
2311 mxge_rx_ring_t *rx;
2189 bus_dmamap_t old_map;
2190 int idx;
2191 uint16_t tcpudp_csum;
2192
2312 bus_dmamap_t old_map;
2313 int idx;
2314 uint16_t tcpudp_csum;
2315
2316 sc = ss->sc;
2193 ifp = sc->ifp;
2317 ifp = sc->ifp;
2194 rx = &sc->rx_big;
2318 rx = &ss->rx_big;
2195 idx = rx->cnt & rx->mask;
2196 rx->cnt += rx->nbufs;
2197 /* save a pointer to the received mbuf */
2198 m = rx->info[idx].m;
2199 /* try to replace the received mbuf */
2319 idx = rx->cnt & rx->mask;
2320 rx->cnt += rx->nbufs;
2321 /* save a pointer to the received mbuf */
2322 m = rx->info[idx].m;
2323 /* try to replace the received mbuf */
2200 if (mxge_get_buf_big(sc, rx->extra_map, idx)) {
2324 if (mxge_get_buf_big(ss, rx->extra_map, idx)) {
2201 /* drop the frame -- the old mbuf is re-cycled */
2202 ifp->if_ierrors++;
2203 return;
2204 }
2205
2206 /* unmap the received buffer */
2207 old_map = rx->info[idx].map;
2208 bus_dmamap_sync(rx->dmat, old_map, BUS_DMASYNC_POSTREAD);

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

2213 rx->extra_map = old_map;
2214
2215 /* mcp implicitly skips 1st 2 bytes so that packet is properly
2216 * aligned */
2217 m->m_data += MXGEFW_PAD;
2218
2219 m->m_pkthdr.rcvif = ifp;
2220 m->m_len = m->m_pkthdr.len = len;
2325 /* drop the frame -- the old mbuf is re-cycled */
2326 ifp->if_ierrors++;
2327 return;
2328 }
2329
2330 /* unmap the received buffer */
2331 old_map = rx->info[idx].map;
2332 bus_dmamap_sync(rx->dmat, old_map, BUS_DMASYNC_POSTREAD);

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

2337 rx->extra_map = old_map;
2338
2339 /* mcp implicitly skips 1st 2 bytes so that packet is properly
2340 * aligned */
2341 m->m_data += MXGEFW_PAD;
2342
2343 m->m_pkthdr.rcvif = ifp;
2344 m->m_len = m->m_pkthdr.len = len;
2221 ifp->if_ipackets++;
2345 ss->ipackets++;
2222 eh = mtod(m, struct ether_header *);
2223 if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
2224 mxge_vlan_tag_remove(m, &csum);
2225 }
2226 /* if the checksum is valid, mark it in the mbuf header */
2227 if (sc->csum_flag && (0 == (tcpudp_csum = mxge_rx_csum(m, csum)))) {
2346 eh = mtod(m, struct ether_header *);
2347 if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
2348 mxge_vlan_tag_remove(m, &csum);
2349 }
2350 /* if the checksum is valid, mark it in the mbuf header */
2351 if (sc->csum_flag && (0 == (tcpudp_csum = mxge_rx_csum(m, csum)))) {
2228 if (sc->lro_cnt && (0 == mxge_lro_rx(sc, m, csum)))
2352 if (sc->lro_cnt && (0 == mxge_lro_rx(ss, m, csum)))
2229 return;
2230 /* otherwise, it was a UDP frame, or a TCP frame which
2231 we could not do LRO on. Tell the stack that the
2232 checksum is good */
2233 m->m_pkthdr.csum_data = 0xffff;
2234 m->m_pkthdr.csum_flags = CSUM_PSEUDO_HDR | CSUM_DATA_VALID;
2235 }
2236 /* pass the frame up the stack */
2237 (*ifp->if_input)(ifp, m);
2238}
2239
2240static inline void
2353 return;
2354 /* otherwise, it was a UDP frame, or a TCP frame which
2355 we could not do LRO on. Tell the stack that the
2356 checksum is good */
2357 m->m_pkthdr.csum_data = 0xffff;
2358 m->m_pkthdr.csum_flags = CSUM_PSEUDO_HDR | CSUM_DATA_VALID;
2359 }
2360 /* pass the frame up the stack */
2361 (*ifp->if_input)(ifp, m);
2362}
2363
2364static inline void
2241mxge_rx_done_small(mxge_softc_t *sc, uint32_t len, uint32_t csum)
2365mxge_rx_done_small(struct mxge_slice_state *ss, uint32_t len, uint32_t csum)
2242{
2366{
2367 mxge_softc_t *sc;
2243 struct ifnet *ifp;
2244 struct ether_header *eh;
2245 struct mbuf *m;
2368 struct ifnet *ifp;
2369 struct ether_header *eh;
2370 struct mbuf *m;
2246 mxge_rx_buf_t *rx;
2371 mxge_rx_ring_t *rx;
2247 bus_dmamap_t old_map;
2248 int idx;
2249 uint16_t tcpudp_csum;
2250
2372 bus_dmamap_t old_map;
2373 int idx;
2374 uint16_t tcpudp_csum;
2375
2376 sc = ss->sc;
2251 ifp = sc->ifp;
2377 ifp = sc->ifp;
2252 rx = &sc->rx_small;
2378 rx = &ss->rx_small;
2253 idx = rx->cnt & rx->mask;
2254 rx->cnt++;
2255 /* save a pointer to the received mbuf */
2256 m = rx->info[idx].m;
2257 /* try to replace the received mbuf */
2379 idx = rx->cnt & rx->mask;
2380 rx->cnt++;
2381 /* save a pointer to the received mbuf */
2382 m = rx->info[idx].m;
2383 /* try to replace the received mbuf */
2258 if (mxge_get_buf_small(sc, rx->extra_map, idx)) {
2384 if (mxge_get_buf_small(ss, rx->extra_map, idx)) {
2259 /* drop the frame -- the old mbuf is re-cycled */
2260 ifp->if_ierrors++;
2261 return;
2262 }
2263
2264 /* unmap the received buffer */
2265 old_map = rx->info[idx].map;
2266 bus_dmamap_sync(rx->dmat, old_map, BUS_DMASYNC_POSTREAD);

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

2271 rx->extra_map = old_map;
2272
2273 /* mcp implicitly skips 1st 2 bytes so that packet is properly
2274 * aligned */
2275 m->m_data += MXGEFW_PAD;
2276
2277 m->m_pkthdr.rcvif = ifp;
2278 m->m_len = m->m_pkthdr.len = len;
2385 /* drop the frame -- the old mbuf is re-cycled */
2386 ifp->if_ierrors++;
2387 return;
2388 }
2389
2390 /* unmap the received buffer */
2391 old_map = rx->info[idx].map;
2392 bus_dmamap_sync(rx->dmat, old_map, BUS_DMASYNC_POSTREAD);

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

2397 rx->extra_map = old_map;
2398
2399 /* mcp implicitly skips 1st 2 bytes so that packet is properly
2400 * aligned */
2401 m->m_data += MXGEFW_PAD;
2402
2403 m->m_pkthdr.rcvif = ifp;
2404 m->m_len = m->m_pkthdr.len = len;
2279 ifp->if_ipackets++;
2405 ss->ipackets++;
2280 eh = mtod(m, struct ether_header *);
2281 if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
2282 mxge_vlan_tag_remove(m, &csum);
2283 }
2284 /* if the checksum is valid, mark it in the mbuf header */
2285 if (sc->csum_flag && (0 == (tcpudp_csum = mxge_rx_csum(m, csum)))) {
2406 eh = mtod(m, struct ether_header *);
2407 if (eh->ether_type == htons(ETHERTYPE_VLAN)) {
2408 mxge_vlan_tag_remove(m, &csum);
2409 }
2410 /* if the checksum is valid, mark it in the mbuf header */
2411 if (sc->csum_flag && (0 == (tcpudp_csum = mxge_rx_csum(m, csum)))) {
2286 if (sc->lro_cnt && (0 == mxge_lro_rx(sc, m, csum)))
2412 if (sc->lro_cnt && (0 == mxge_lro_rx(ss, m, csum)))
2287 return;
2288 /* otherwise, it was a UDP frame, or a TCP frame which
2289 we could not do LRO on. Tell the stack that the
2290 checksum is good */
2291 m->m_pkthdr.csum_data = 0xffff;
2292 m->m_pkthdr.csum_flags = CSUM_PSEUDO_HDR | CSUM_DATA_VALID;
2293 }
2413 return;
2414 /* otherwise, it was a UDP frame, or a TCP frame which
2415 we could not do LRO on. Tell the stack that the
2416 checksum is good */
2417 m->m_pkthdr.csum_data = 0xffff;
2418 m->m_pkthdr.csum_flags = CSUM_PSEUDO_HDR | CSUM_DATA_VALID;
2419 }
2294
2295 /* pass the frame up the stack */
2296 (*ifp->if_input)(ifp, m);
2297}
2298
2299static inline void
2420 /* pass the frame up the stack */
2421 (*ifp->if_input)(ifp, m);
2422}
2423
2424static inline void
2300mxge_clean_rx_done(mxge_softc_t *sc)
2425mxge_clean_rx_done(struct mxge_slice_state *ss)
2301{
2426{
2302 mxge_rx_done_t *rx_done = &sc->rx_done;
2427 mxge_rx_done_t *rx_done = &ss->rx_done;
2303 struct lro_entry *lro;
2304 int limit = 0;
2305 uint16_t length;
2306 uint16_t checksum;
2307
2308
2309 while (rx_done->entry[rx_done->idx].length != 0) {
2310 length = ntohs(rx_done->entry[rx_done->idx].length);
2311 rx_done->entry[rx_done->idx].length = 0;
2312 checksum = rx_done->entry[rx_done->idx].checksum;
2313 if (length <= (MHLEN - MXGEFW_PAD))
2428 struct lro_entry *lro;
2429 int limit = 0;
2430 uint16_t length;
2431 uint16_t checksum;
2432
2433
2434 while (rx_done->entry[rx_done->idx].length != 0) {
2435 length = ntohs(rx_done->entry[rx_done->idx].length);
2436 rx_done->entry[rx_done->idx].length = 0;
2437 checksum = rx_done->entry[rx_done->idx].checksum;
2438 if (length <= (MHLEN - MXGEFW_PAD))
2314 mxge_rx_done_small(sc, length, checksum);
2439 mxge_rx_done_small(ss, length, checksum);
2315 else
2440 else
2316 mxge_rx_done_big(sc, length, checksum);
2441 mxge_rx_done_big(ss, length, checksum);
2317 rx_done->cnt++;
2318 rx_done->idx = rx_done->cnt & rx_done->mask;
2319
2320 /* limit potential for livelock */
2321 if (__predict_false(++limit > rx_done->mask / 2))
2322 break;
2323 }
2442 rx_done->cnt++;
2443 rx_done->idx = rx_done->cnt & rx_done->mask;
2444
2445 /* limit potential for livelock */
2446 if (__predict_false(++limit > rx_done->mask / 2))
2447 break;
2448 }
2324 while(!SLIST_EMPTY(&sc->lro_active)) {
2325 lro = SLIST_FIRST(&sc->lro_active);
2326 SLIST_REMOVE_HEAD(&sc->lro_active, next);
2327 mxge_lro_flush(sc, lro);
2449 while (!SLIST_EMPTY(&ss->lro_active)) {
2450 lro = SLIST_FIRST(&ss->lro_active);
2451 SLIST_REMOVE_HEAD(&ss->lro_active, next);
2452 mxge_lro_flush(ss, lro);
2328 }
2329}
2330
2331
2332static inline void
2453 }
2454}
2455
2456
2457static inline void
2333mxge_tx_done(mxge_softc_t *sc, uint32_t mcp_idx)
2458mxge_tx_done(struct mxge_slice_state *ss, uint32_t mcp_idx)
2334{
2335 struct ifnet *ifp;
2459{
2460 struct ifnet *ifp;
2336 mxge_tx_buf_t *tx;
2461 mxge_tx_ring_t *tx;
2337 struct mbuf *m;
2338 bus_dmamap_t map;
2339 int idx;
2340
2462 struct mbuf *m;
2463 bus_dmamap_t map;
2464 int idx;
2465
2341 tx = &sc->tx;
2342 ifp = sc->ifp;
2466 tx = &ss->tx;
2467 ifp = ss->sc->ifp;
2343 while (tx->pkt_done != mcp_idx) {
2344 idx = tx->done & tx->mask;
2345 tx->done++;
2346 m = tx->info[idx].m;
2347 /* mbuf and DMA map only attached to the first
2348 segment per-mbuf */
2349 if (m != NULL) {
2350 ifp->if_opackets++;

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

2359 }
2360 }
2361
2362 /* If we have space, clear IFF_OACTIVE to tell the stack that
2363 its OK to send packets */
2364
2365 if (ifp->if_drv_flags & IFF_DRV_OACTIVE &&
2366 tx->req - tx->done < (tx->mask + 1)/4) {
2468 while (tx->pkt_done != mcp_idx) {
2469 idx = tx->done & tx->mask;
2470 tx->done++;
2471 m = tx->info[idx].m;
2472 /* mbuf and DMA map only attached to the first
2473 segment per-mbuf */
2474 if (m != NULL) {
2475 ifp->if_opackets++;

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

2484 }
2485 }
2486
2487 /* If we have space, clear IFF_OACTIVE to tell the stack that
2488 its OK to send packets */
2489
2490 if (ifp->if_drv_flags & IFF_DRV_OACTIVE &&
2491 tx->req - tx->done < (tx->mask + 1)/4) {
2367 mtx_lock(&sc->tx_mtx);
2492 mtx_lock(&ss->tx.mtx);
2368 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2493 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
2369 sc->tx.wake++;
2370 mxge_start_locked(sc);
2371 mtx_unlock(&sc->tx_mtx);
2494 ss->tx.wake++;
2495 mxge_start_locked(ss);
2496 mtx_unlock(&ss->tx.mtx);
2372 }
2373}
2374
2375static struct mxge_media_type mxge_media_types[] =
2376{
2377 {IFM_10G_CX4, 0x7f, "10GBASE-CX4 (module)"},
2378 {IFM_10G_SR, (1 << 7), "10GBASE-SR"},
2379 {IFM_10G_LR, (1 << 6), "10GBASE-LR"},

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

2506 device_printf(sc->dev, "XFP media 0x%x unknown\n", cmd.data0);
2507
2508 return;
2509}
2510
2511static void
2512mxge_intr(void *arg)
2513{
2497 }
2498}
2499
2500static struct mxge_media_type mxge_media_types[] =
2501{
2502 {IFM_10G_CX4, 0x7f, "10GBASE-CX4 (module)"},
2503 {IFM_10G_SR, (1 << 7), "10GBASE-SR"},
2504 {IFM_10G_LR, (1 << 6), "10GBASE-LR"},

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

2631 device_printf(sc->dev, "XFP media 0x%x unknown\n", cmd.data0);
2632
2633 return;
2634}
2635
2636static void
2637mxge_intr(void *arg)
2638{
2514 mxge_softc_t *sc = arg;
2515 mcp_irq_data_t *stats = sc->fw_stats;
2516 mxge_tx_buf_t *tx = &sc->tx;
2517 mxge_rx_done_t *rx_done = &sc->rx_done;
2639 struct mxge_slice_state *ss = arg;
2640 mxge_softc_t *sc = ss->sc;
2641 mcp_irq_data_t *stats = ss->fw_stats;
2642 mxge_tx_ring_t *tx = &ss->tx;
2643 mxge_rx_done_t *rx_done = &ss->rx_done;
2518 uint32_t send_done_count;
2519 uint8_t valid;
2520
2521
2644 uint32_t send_done_count;
2645 uint8_t valid;
2646
2647
2648 /* an interrupt on a non-zero slice is implicitly valid
2649 since MSI-X irqs are not shared */
2650 if (ss != sc->ss) {
2651 mxge_clean_rx_done(ss);
2652 *ss->irq_claim = be32toh(3);
2653 return;
2654 }
2655
2522 /* make sure the DMA has finished */
2523 if (!stats->valid) {
2524 return;
2525 }
2526 valid = stats->valid;
2527
2528 if (!sc->msi_enabled) {
2529 /* lower legacy IRQ */

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

2536 }
2537
2538 /* loop while waiting for legacy irq deassertion */
2539 do {
2540 /* check for transmit completes and receives */
2541 send_done_count = be32toh(stats->send_done_count);
2542 while ((send_done_count != tx->pkt_done) ||
2543 (rx_done->entry[rx_done->idx].length != 0)) {
2656 /* make sure the DMA has finished */
2657 if (!stats->valid) {
2658 return;
2659 }
2660 valid = stats->valid;
2661
2662 if (!sc->msi_enabled) {
2663 /* lower legacy IRQ */

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

2670 }
2671
2672 /* loop while waiting for legacy irq deassertion */
2673 do {
2674 /* check for transmit completes and receives */
2675 send_done_count = be32toh(stats->send_done_count);
2676 while ((send_done_count != tx->pkt_done) ||
2677 (rx_done->entry[rx_done->idx].length != 0)) {
2544 mxge_tx_done(sc, (int)send_done_count);
2545 mxge_clean_rx_done(sc);
2678 mxge_tx_done(ss, (int)send_done_count);
2679 mxge_clean_rx_done(ss);
2546 send_done_count = be32toh(stats->send_done_count);
2547 }
2548 } while (*((volatile uint8_t *) &stats->valid));
2549
2550 if (__predict_false(stats->stats_updated)) {
2551 if (sc->link_state != stats->link_up) {
2552 sc->link_state = stats->link_up;
2553 if (sc->link_state) {
2554 if_link_state_change(sc->ifp, LINK_STATE_UP);
2555 if (mxge_verbose)
2556 device_printf(sc->dev, "link up\n");
2557 } else {
2558 if_link_state_change(sc->ifp, LINK_STATE_DOWN);
2559 if (mxge_verbose)
2560 device_printf(sc->dev, "link down\n");
2561 }
2562 sc->need_media_probe = 1;
2563 }
2564 if (sc->rdma_tags_available !=
2680 send_done_count = be32toh(stats->send_done_count);
2681 }
2682 } while (*((volatile uint8_t *) &stats->valid));
2683
2684 if (__predict_false(stats->stats_updated)) {
2685 if (sc->link_state != stats->link_up) {
2686 sc->link_state = stats->link_up;
2687 if (sc->link_state) {
2688 if_link_state_change(sc->ifp, LINK_STATE_UP);
2689 if (mxge_verbose)
2690 device_printf(sc->dev, "link up\n");
2691 } else {
2692 if_link_state_change(sc->ifp, LINK_STATE_DOWN);
2693 if (mxge_verbose)
2694 device_printf(sc->dev, "link down\n");
2695 }
2696 sc->need_media_probe = 1;
2697 }
2698 if (sc->rdma_tags_available !=
2565 be32toh(sc->fw_stats->rdma_tags_available)) {
2699 be32toh(stats->rdma_tags_available)) {
2566 sc->rdma_tags_available =
2700 sc->rdma_tags_available =
2567 be32toh(sc->fw_stats->rdma_tags_available);
2701 be32toh(stats->rdma_tags_available);
2568 device_printf(sc->dev, "RDMA timed out! %d tags "
2569 "left\n", sc->rdma_tags_available);
2570 }
2571
2572 if (stats->link_down) {
2573 sc->down_cnt += stats->link_down;
2574 sc->link_state = 0;
2575 if_link_state_change(sc->ifp, LINK_STATE_DOWN);
2576 }
2577 }
2578
2579 /* check to see if we have rx token to pass back */
2580 if (valid & 0x1)
2702 device_printf(sc->dev, "RDMA timed out! %d tags "
2703 "left\n", sc->rdma_tags_available);
2704 }
2705
2706 if (stats->link_down) {
2707 sc->down_cnt += stats->link_down;
2708 sc->link_state = 0;
2709 if_link_state_change(sc->ifp, LINK_STATE_DOWN);
2710 }
2711 }
2712
2713 /* check to see if we have rx token to pass back */
2714 if (valid & 0x1)
2581 *sc->irq_claim = be32toh(3);
2582 *(sc->irq_claim + 1) = be32toh(3);
2715 *ss->irq_claim = be32toh(3);
2716 *(ss->irq_claim + 1) = be32toh(3);
2583}
2584
2585static void
2586mxge_init(void *arg)
2587{
2588}
2589
2590
2591
2592static void
2717}
2718
2719static void
2720mxge_init(void *arg)
2721{
2722}
2723
2724
2725
2726static void
2593mxge_free_mbufs(mxge_softc_t *sc)
2727mxge_free_slice_mbufs(struct mxge_slice_state *ss)
2594{
2728{
2729 struct lro_entry *lro_entry;
2595 int i;
2596
2730 int i;
2731
2597 for (i = 0; i <= sc->rx_big.mask; i++) {
2598 if (sc->rx_big.info[i].m == NULL)
2732 while (!SLIST_EMPTY(&ss->lro_free)) {
2733 lro_entry = SLIST_FIRST(&ss->lro_free);
2734 SLIST_REMOVE_HEAD(&ss->lro_free, next);
2735 free(lro_entry, M_DEVBUF);
2736 }
2737
2738 for (i = 0; i <= ss->rx_big.mask; i++) {
2739 if (ss->rx_big.info[i].m == NULL)
2599 continue;
2740 continue;
2600 bus_dmamap_unload(sc->rx_big.dmat,
2601 sc->rx_big.info[i].map);
2602 m_freem(sc->rx_big.info[i].m);
2603 sc->rx_big.info[i].m = NULL;
2741 bus_dmamap_unload(ss->rx_big.dmat,
2742 ss->rx_big.info[i].map);
2743 m_freem(ss->rx_big.info[i].m);
2744 ss->rx_big.info[i].m = NULL;
2604 }
2605
2745 }
2746
2606 for (i = 0; i <= sc->rx_small.mask; i++) {
2607 if (sc->rx_small.info[i].m == NULL)
2747 for (i = 0; i <= ss->rx_small.mask; i++) {
2748 if (ss->rx_small.info[i].m == NULL)
2608 continue;
2749 continue;
2609 bus_dmamap_unload(sc->rx_small.dmat,
2610 sc->rx_small.info[i].map);
2611 m_freem(sc->rx_small.info[i].m);
2612 sc->rx_small.info[i].m = NULL;
2750 bus_dmamap_unload(ss->rx_small.dmat,
2751 ss->rx_small.info[i].map);
2752 m_freem(ss->rx_small.info[i].m);
2753 ss->rx_small.info[i].m = NULL;
2613 }
2614
2754 }
2755
2615 for (i = 0; i <= sc->tx.mask; i++) {
2616 sc->tx.info[i].flag = 0;
2617 if (sc->tx.info[i].m == NULL)
2756 /* transmit ring used only on the first slice */
2757 if (ss->tx.info == NULL)
2758 return;
2759
2760 for (i = 0; i <= ss->tx.mask; i++) {
2761 ss->tx.info[i].flag = 0;
2762 if (ss->tx.info[i].m == NULL)
2618 continue;
2763 continue;
2619 bus_dmamap_unload(sc->tx.dmat,
2620 sc->tx.info[i].map);
2621 m_freem(sc->tx.info[i].m);
2622 sc->tx.info[i].m = NULL;
2764 bus_dmamap_unload(ss->tx.dmat,
2765 ss->tx.info[i].map);
2766 m_freem(ss->tx.info[i].m);
2767 ss->tx.info[i].m = NULL;
2623 }
2624}
2625
2626static void
2768 }
2769}
2770
2771static void
2627mxge_free_rings(mxge_softc_t *sc)
2772mxge_free_mbufs(mxge_softc_t *sc)
2628{
2773{
2774 int slice;
2775
2776 for (slice = 0; slice < sc->num_slices; slice++)
2777 mxge_free_slice_mbufs(&sc->ss[slice]);
2778}
2779
2780static void
2781mxge_free_slice_rings(struct mxge_slice_state *ss)
2782{
2629 int i;
2630
2783 int i;
2784
2631 if (sc->rx_done.entry != NULL)
2632 mxge_dma_free(&sc->rx_done.dma);
2633 sc->rx_done.entry = NULL;
2634 if (sc->tx.req_bytes != NULL)
2635 free(sc->tx.req_bytes, M_DEVBUF);
2636 if (sc->tx.seg_list != NULL)
2637 free(sc->tx.seg_list, M_DEVBUF);
2638 if (sc->rx_small.shadow != NULL)
2639 free(sc->rx_small.shadow, M_DEVBUF);
2640 if (sc->rx_big.shadow != NULL)
2641 free(sc->rx_big.shadow, M_DEVBUF);
2642 if (sc->tx.info != NULL) {
2643 if (sc->tx.dmat != NULL) {
2644 for (i = 0; i <= sc->tx.mask; i++) {
2645 bus_dmamap_destroy(sc->tx.dmat,
2646 sc->tx.info[i].map);
2785
2786 if (ss->rx_done.entry != NULL)
2787 mxge_dma_free(&ss->rx_done.dma);
2788 ss->rx_done.entry = NULL;
2789
2790 if (ss->tx.req_bytes != NULL)
2791 free(ss->tx.req_bytes, M_DEVBUF);
2792 ss->tx.req_bytes = NULL;
2793
2794 if (ss->tx.seg_list != NULL)
2795 free(ss->tx.seg_list, M_DEVBUF);
2796 ss->tx.seg_list = NULL;
2797
2798 if (ss->rx_small.shadow != NULL)
2799 free(ss->rx_small.shadow, M_DEVBUF);
2800 ss->rx_small.shadow = NULL;
2801
2802 if (ss->rx_big.shadow != NULL)
2803 free(ss->rx_big.shadow, M_DEVBUF);
2804 ss->rx_big.shadow = NULL;
2805
2806 if (ss->tx.info != NULL) {
2807 if (ss->tx.dmat != NULL) {
2808 for (i = 0; i <= ss->tx.mask; i++) {
2809 bus_dmamap_destroy(ss->tx.dmat,
2810 ss->tx.info[i].map);
2647 }
2811 }
2648 bus_dma_tag_destroy(sc->tx.dmat);
2812 bus_dma_tag_destroy(ss->tx.dmat);
2649 }
2813 }
2650 free(sc->tx.info, M_DEVBUF);
2814 free(ss->tx.info, M_DEVBUF);
2651 }
2815 }
2652 if (sc->rx_small.info != NULL) {
2653 if (sc->rx_small.dmat != NULL) {
2654 for (i = 0; i <= sc->rx_small.mask; i++) {
2655 bus_dmamap_destroy(sc->rx_small.dmat,
2656 sc->rx_small.info[i].map);
2816 ss->tx.info = NULL;
2817
2818 if (ss->rx_small.info != NULL) {
2819 if (ss->rx_small.dmat != NULL) {
2820 for (i = 0; i <= ss->rx_small.mask; i++) {
2821 bus_dmamap_destroy(ss->rx_small.dmat,
2822 ss->rx_small.info[i].map);
2657 }
2823 }
2658 bus_dmamap_destroy(sc->rx_small.dmat,
2659 sc->rx_small.extra_map);
2660 bus_dma_tag_destroy(sc->rx_small.dmat);
2824 bus_dmamap_destroy(ss->rx_small.dmat,
2825 ss->rx_small.extra_map);
2826 bus_dma_tag_destroy(ss->rx_small.dmat);
2661 }
2827 }
2662 free(sc->rx_small.info, M_DEVBUF);
2828 free(ss->rx_small.info, M_DEVBUF);
2663 }
2829 }
2664 if (sc->rx_big.info != NULL) {
2665 if (sc->rx_big.dmat != NULL) {
2666 for (i = 0; i <= sc->rx_big.mask; i++) {
2667 bus_dmamap_destroy(sc->rx_big.dmat,
2668 sc->rx_big.info[i].map);
2830 ss->rx_small.info = NULL;
2831
2832 if (ss->rx_big.info != NULL) {
2833 if (ss->rx_big.dmat != NULL) {
2834 for (i = 0; i <= ss->rx_big.mask; i++) {
2835 bus_dmamap_destroy(ss->rx_big.dmat,
2836 ss->rx_big.info[i].map);
2669 }
2837 }
2670 bus_dmamap_destroy(sc->rx_big.dmat,
2671 sc->rx_big.extra_map);
2672 bus_dma_tag_destroy(sc->rx_big.dmat);
2838 bus_dmamap_destroy(ss->rx_big.dmat,
2839 ss->rx_big.extra_map);
2840 bus_dma_tag_destroy(ss->rx_big.dmat);
2673 }
2841 }
2674 free(sc->rx_big.info, M_DEVBUF);
2842 free(ss->rx_big.info, M_DEVBUF);
2675 }
2843 }
2844 ss->rx_big.info = NULL;
2676}
2677
2845}
2846
2678static int
2679mxge_alloc_rings(mxge_softc_t *sc)
2847static void
2848mxge_free_rings(mxge_softc_t *sc)
2680{
2849{
2681 mxge_cmd_t cmd;
2682 int tx_ring_size, rx_ring_size;
2683 int tx_ring_entries, rx_ring_entries;
2684 int i, err;
2685 unsigned long bytes;
2686
2687 /* get ring sizes */
2688 err = mxge_send_cmd(sc, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd);
2689 tx_ring_size = cmd.data0;
2690 err |= mxge_send_cmd(sc, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd);
2691 if (err != 0) {
2692 device_printf(sc->dev, "Cannot determine ring sizes\n");
2693 goto abort_with_nothing;
2694 }
2850 int slice;
2695
2851
2696 rx_ring_size = cmd.data0;
2852 for (slice = 0; slice < sc->num_slices; slice++)
2853 mxge_free_slice_rings(&sc->ss[slice]);
2854}
2697
2855
2698 tx_ring_entries = tx_ring_size / sizeof (mcp_kreq_ether_send_t);
2699 rx_ring_entries = rx_ring_size / sizeof (mcp_dma_addr_t);
2700 IFQ_SET_MAXLEN(&sc->ifp->if_snd, tx_ring_entries - 1);
2701 sc->ifp->if_snd.ifq_drv_maxlen = sc->ifp->if_snd.ifq_maxlen;
2702 IFQ_SET_READY(&sc->ifp->if_snd);
2856static int
2857mxge_alloc_slice_rings(struct mxge_slice_state *ss, int rx_ring_entries,
2858 int tx_ring_entries)
2859{
2860 mxge_softc_t *sc = ss->sc;
2861 size_t bytes;
2862 int err, i;
2703
2863
2704 sc->tx.mask = tx_ring_entries - 1;
2705 sc->tx.max_desc = MIN(MXGE_MAX_SEND_DESC, tx_ring_entries / 4);
2706 sc->rx_small.mask = sc->rx_big.mask = rx_ring_entries - 1;
2707 sc->rx_done.mask = (2 * rx_ring_entries) - 1;
2708
2709 err = ENOMEM;
2710
2864 err = ENOMEM;
2865
2711 /* allocate interrupt queues */
2712 bytes = (sc->rx_done.mask + 1) * sizeof (*sc->rx_done.entry);
2713 err = mxge_dma_alloc(sc, &sc->rx_done.dma, bytes, 4096);
2714 if (err != 0)
2715 goto abort_with_nothing;
2716 sc->rx_done.entry = sc->rx_done.dma.addr;
2717 bzero(sc->rx_done.entry, bytes);
2866 /* allocate per-slice receive resources */
2718
2867
2719 /* allocate the tx request copy block */
2720 bytes = 8 +
2721 sizeof (*sc->tx.req_list) * (sc->tx.max_desc + 4);
2722 sc->tx.req_bytes = malloc(bytes, M_DEVBUF, M_WAITOK);
2723 if (sc->tx.req_bytes == NULL)
2724 goto abort_with_alloc;
2725 /* ensure req_list entries are aligned to 8 bytes */
2726 sc->tx.req_list = (mcp_kreq_ether_send_t *)
2727 ((unsigned long)(sc->tx.req_bytes + 7) & ~7UL);
2868 ss->rx_small.mask = ss->rx_big.mask = rx_ring_entries - 1;
2869 ss->rx_done.mask = (2 * rx_ring_entries) - 1;
2728
2870
2729 /* allocate the tx busdma segment list */
2730 bytes = sizeof (*sc->tx.seg_list) * sc->tx.max_desc;
2731 sc->tx.seg_list = (bus_dma_segment_t *)
2732 malloc(bytes, M_DEVBUF, M_WAITOK);
2733 if (sc->tx.seg_list == NULL)
2734 goto abort_with_alloc;
2735
2736 /* allocate the rx shadow rings */
2871 /* allocate the rx shadow rings */
2737 bytes = rx_ring_entries * sizeof (*sc->rx_small.shadow);
2738 sc->rx_small.shadow = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2739 if (sc->rx_small.shadow == NULL)
2740 goto abort_with_alloc;
2872 bytes = rx_ring_entries * sizeof (*ss->rx_small.shadow);
2873 ss->rx_small.shadow = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2874 if (ss->rx_small.shadow == NULL)
2875 return err;;
2741
2876
2742 bytes = rx_ring_entries * sizeof (*sc->rx_big.shadow);
2743 sc->rx_big.shadow = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2744 if (sc->rx_big.shadow == NULL)
2745 goto abort_with_alloc;
2877 bytes = rx_ring_entries * sizeof (*ss->rx_big.shadow);
2878 ss->rx_big.shadow = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2879 if (ss->rx_big.shadow == NULL)
2880 return err;;
2746
2881
2747 /* allocate the host info rings */
2748 bytes = tx_ring_entries * sizeof (*sc->tx.info);
2749 sc->tx.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2750 if (sc->tx.info == NULL)
2751 goto abort_with_alloc;
2752
2753 bytes = rx_ring_entries * sizeof (*sc->rx_small.info);
2754 sc->rx_small.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2755 if (sc->rx_small.info == NULL)
2756 goto abort_with_alloc;
2882 /* allocate the rx host info rings */
2883 bytes = rx_ring_entries * sizeof (*ss->rx_small.info);
2884 ss->rx_small.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2885 if (ss->rx_small.info == NULL)
2886 return err;;
2757
2887
2758 bytes = rx_ring_entries * sizeof (*sc->rx_big.info);
2759 sc->rx_big.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2760 if (sc->rx_big.info == NULL)
2761 goto abort_with_alloc;
2888 bytes = rx_ring_entries * sizeof (*ss->rx_big.info);
2889 ss->rx_big.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2890 if (ss->rx_big.info == NULL)
2891 return err;;
2762
2892
2763 /* allocate the busdma resources */
2893 /* allocate the rx busdma resources */
2764 err = bus_dma_tag_create(sc->parent_dmat, /* parent */
2765 1, /* alignment */
2894 err = bus_dma_tag_create(sc->parent_dmat, /* parent */
2895 1, /* alignment */
2766 sc->tx.boundary, /* boundary */
2767 BUS_SPACE_MAXADDR, /* low */
2768 BUS_SPACE_MAXADDR, /* high */
2769 NULL, NULL, /* filter */
2770 65536 + 256, /* maxsize */
2771 sc->tx.max_desc - 2, /* num segs */
2772 sc->tx.boundary, /* maxsegsize */
2773 BUS_DMA_ALLOCNOW, /* flags */
2774 NULL, NULL, /* lock */
2775 &sc->tx.dmat); /* tag */
2776
2777 if (err != 0) {
2778 device_printf(sc->dev, "Err %d allocating tx dmat\n",
2779 err);
2780 goto abort_with_alloc;
2781 }
2782
2783 err = bus_dma_tag_create(sc->parent_dmat, /* parent */
2784 1, /* alignment */
2785 4096, /* boundary */
2786 BUS_SPACE_MAXADDR, /* low */
2787 BUS_SPACE_MAXADDR, /* high */
2788 NULL, NULL, /* filter */
2789 MHLEN, /* maxsize */
2790 1, /* num segs */
2791 MHLEN, /* maxsegsize */
2792 BUS_DMA_ALLOCNOW, /* flags */
2793 NULL, NULL, /* lock */
2896 4096, /* boundary */
2897 BUS_SPACE_MAXADDR, /* low */
2898 BUS_SPACE_MAXADDR, /* high */
2899 NULL, NULL, /* filter */
2900 MHLEN, /* maxsize */
2901 1, /* num segs */
2902 MHLEN, /* maxsegsize */
2903 BUS_DMA_ALLOCNOW, /* flags */
2904 NULL, NULL, /* lock */
2794 &sc->rx_small.dmat); /* tag */
2905 &ss->rx_small.dmat); /* tag */
2795 if (err != 0) {
2796 device_printf(sc->dev, "Err %d allocating rx_small dmat\n",
2797 err);
2906 if (err != 0) {
2907 device_printf(sc->dev, "Err %d allocating rx_small dmat\n",
2908 err);
2798 goto abort_with_alloc;
2909 return err;;
2799 }
2800
2801 err = bus_dma_tag_create(sc->parent_dmat, /* parent */
2802 1, /* alignment */
2803 4096, /* boundary */
2804 BUS_SPACE_MAXADDR, /* low */
2805 BUS_SPACE_MAXADDR, /* high */
2806 NULL, NULL, /* filter */
2807 3*4096, /* maxsize */
2808 3, /* num segs */
2809 4096, /* maxsegsize */
2810 BUS_DMA_ALLOCNOW, /* flags */
2811 NULL, NULL, /* lock */
2910 }
2911
2912 err = bus_dma_tag_create(sc->parent_dmat, /* parent */
2913 1, /* alignment */
2914 4096, /* boundary */
2915 BUS_SPACE_MAXADDR, /* low */
2916 BUS_SPACE_MAXADDR, /* high */
2917 NULL, NULL, /* filter */
2918 3*4096, /* maxsize */
2919 3, /* num segs */
2920 4096, /* maxsegsize */
2921 BUS_DMA_ALLOCNOW, /* flags */
2922 NULL, NULL, /* lock */
2812 &sc->rx_big.dmat); /* tag */
2923 &ss->rx_big.dmat); /* tag */
2813 if (err != 0) {
2814 device_printf(sc->dev, "Err %d allocating rx_big dmat\n",
2815 err);
2924 if (err != 0) {
2925 device_printf(sc->dev, "Err %d allocating rx_big dmat\n",
2926 err);
2816 goto abort_with_alloc;
2927 return err;;
2817 }
2928 }
2818
2819 /* now use these tags to setup dmamaps for each slot
2820 in each ring */
2821 for (i = 0; i <= sc->tx.mask; i++) {
2822 err = bus_dmamap_create(sc->tx.dmat, 0,
2823 &sc->tx.info[i].map);
2929 for (i = 0; i <= ss->rx_small.mask; i++) {
2930 err = bus_dmamap_create(ss->rx_small.dmat, 0,
2931 &ss->rx_small.info[i].map);
2824 if (err != 0) {
2932 if (err != 0) {
2825 device_printf(sc->dev, "Err %d tx dmamap\n",
2826 err);
2827 goto abort_with_alloc;
2828 }
2829 }
2830 for (i = 0; i <= sc->rx_small.mask; i++) {
2831 err = bus_dmamap_create(sc->rx_small.dmat, 0,
2832 &sc->rx_small.info[i].map);
2833 if (err != 0) {
2834 device_printf(sc->dev, "Err %d rx_small dmamap\n",
2835 err);
2933 device_printf(sc->dev, "Err %d rx_small dmamap\n",
2934 err);
2836 goto abort_with_alloc;
2935 return err;;
2837 }
2838 }
2936 }
2937 }
2839 err = bus_dmamap_create(sc->rx_small.dmat, 0,
2840 &sc->rx_small.extra_map);
2938 err = bus_dmamap_create(ss->rx_small.dmat, 0,
2939 &ss->rx_small.extra_map);
2841 if (err != 0) {
2842 device_printf(sc->dev, "Err %d extra rx_small dmamap\n",
2843 err);
2940 if (err != 0) {
2941 device_printf(sc->dev, "Err %d extra rx_small dmamap\n",
2942 err);
2844 goto abort_with_alloc;
2943 return err;;
2845 }
2846
2944 }
2945
2847 for (i = 0; i <= sc->rx_big.mask; i++) {
2848 err = bus_dmamap_create(sc->rx_big.dmat, 0,
2849 &sc->rx_big.info[i].map);
2946 for (i = 0; i <= ss->rx_big.mask; i++) {
2947 err = bus_dmamap_create(ss->rx_big.dmat, 0,
2948 &ss->rx_big.info[i].map);
2850 if (err != 0) {
2851 device_printf(sc->dev, "Err %d rx_big dmamap\n",
2949 if (err != 0) {
2950 device_printf(sc->dev, "Err %d rx_big dmamap\n",
2852 err);
2853 goto abort_with_alloc;
2951 err);
2952 return err;;
2854 }
2855 }
2953 }
2954 }
2856 err = bus_dmamap_create(sc->rx_big.dmat, 0,
2857 &sc->rx_big.extra_map);
2955 err = bus_dmamap_create(ss->rx_big.dmat, 0,
2956 &ss->rx_big.extra_map);
2858 if (err != 0) {
2859 device_printf(sc->dev, "Err %d extra rx_big dmamap\n",
2860 err);
2957 if (err != 0) {
2958 device_printf(sc->dev, "Err %d extra rx_big dmamap\n",
2959 err);
2861 goto abort_with_alloc;
2960 return err;;
2862 }
2961 }
2962
2963 /* now allocate TX resouces */
2964
2965 /* only use a single TX ring for now */
2966 if (ss != ss->sc->ss)
2967 return 0;
2968
2969 ss->tx.mask = tx_ring_entries - 1;
2970 ss->tx.max_desc = MIN(MXGE_MAX_SEND_DESC, tx_ring_entries / 4);
2971
2972
2973 /* allocate the tx request copy block */
2974 bytes = 8 +
2975 sizeof (*ss->tx.req_list) * (ss->tx.max_desc + 4);
2976 ss->tx.req_bytes = malloc(bytes, M_DEVBUF, M_WAITOK);
2977 if (ss->tx.req_bytes == NULL)
2978 return err;;
2979 /* ensure req_list entries are aligned to 8 bytes */
2980 ss->tx.req_list = (mcp_kreq_ether_send_t *)
2981 ((unsigned long)(ss->tx.req_bytes + 7) & ~7UL);
2982
2983 /* allocate the tx busdma segment list */
2984 bytes = sizeof (*ss->tx.seg_list) * ss->tx.max_desc;
2985 ss->tx.seg_list = (bus_dma_segment_t *)
2986 malloc(bytes, M_DEVBUF, M_WAITOK);
2987 if (ss->tx.seg_list == NULL)
2988 return err;;
2989
2990 /* allocate the tx host info ring */
2991 bytes = tx_ring_entries * sizeof (*ss->tx.info);
2992 ss->tx.info = malloc(bytes, M_DEVBUF, M_ZERO|M_WAITOK);
2993 if (ss->tx.info == NULL)
2994 return err;;
2995
2996 /* allocate the tx busdma resources */
2997 err = bus_dma_tag_create(sc->parent_dmat, /* parent */
2998 1, /* alignment */
2999 sc->tx_boundary, /* boundary */
3000 BUS_SPACE_MAXADDR, /* low */
3001 BUS_SPACE_MAXADDR, /* high */
3002 NULL, NULL, /* filter */
3003 65536 + 256, /* maxsize */
3004 ss->tx.max_desc - 2, /* num segs */
3005 sc->tx_boundary, /* maxsegsz */
3006 BUS_DMA_ALLOCNOW, /* flags */
3007 NULL, NULL, /* lock */
3008 &ss->tx.dmat); /* tag */
3009
3010 if (err != 0) {
3011 device_printf(sc->dev, "Err %d allocating tx dmat\n",
3012 err);
3013 return err;;
3014 }
3015
3016 /* now use these tags to setup dmamaps for each slot
3017 in the ring */
3018 for (i = 0; i <= ss->tx.mask; i++) {
3019 err = bus_dmamap_create(ss->tx.dmat, 0,
3020 &ss->tx.info[i].map);
3021 if (err != 0) {
3022 device_printf(sc->dev, "Err %d tx dmamap\n",
3023 err);
3024 return err;;
3025 }
3026 }
2863 return 0;
2864
3027 return 0;
3028
2865abort_with_alloc:
2866 mxge_free_rings(sc);
3029}
2867
3030
2868abort_with_nothing:
3031static int
3032mxge_alloc_rings(mxge_softc_t *sc)
3033{
3034 mxge_cmd_t cmd;
3035 int tx_ring_size;
3036 int tx_ring_entries, rx_ring_entries;
3037 int err, slice;
3038
3039 /* get ring sizes */
3040 err = mxge_send_cmd(sc, MXGEFW_CMD_GET_SEND_RING_SIZE, &cmd);
3041 tx_ring_size = cmd.data0;
3042 if (err != 0) {
3043 device_printf(sc->dev, "Cannot determine tx ring sizes\n");
3044 goto abort;
3045 }
3046
3047 tx_ring_entries = tx_ring_size / sizeof (mcp_kreq_ether_send_t);
3048 rx_ring_entries = sc->rx_ring_size / sizeof (mcp_dma_addr_t);
3049 IFQ_SET_MAXLEN(&sc->ifp->if_snd, tx_ring_entries - 1);
3050 sc->ifp->if_snd.ifq_drv_maxlen = sc->ifp->if_snd.ifq_maxlen;
3051 IFQ_SET_READY(&sc->ifp->if_snd);
3052
3053 for (slice = 0; slice < sc->num_slices; slice++) {
3054 err = mxge_alloc_slice_rings(&sc->ss[slice],
3055 rx_ring_entries,
3056 tx_ring_entries);
3057 if (err != 0)
3058 goto abort;
3059 }
3060 return 0;
3061
3062abort:
3063 mxge_free_rings(sc);
2869 return err;
3064 return err;
3065
2870}
2871
3066}
3067
3068
2872static void
2873mxge_choose_params(int mtu, int *big_buf_size, int *cl_size, int *nbufs)
2874{
2875 int bufsize = mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + MXGEFW_PAD;
2876
2877 if (bufsize < MCLBYTES) {
2878 /* easy, everything fits in a single buffer */
2879 *big_buf_size = MCLBYTES;

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

2893 *cl_size = MJUM9BYTES;
2894 *big_buf_size = 4096;
2895 *nbufs = mtu / 4096 + 1;
2896 /* needs to be a power of two, so round up */
2897 if (*nbufs == 3)
2898 *nbufs = 4;
2899}
2900
3069static void
3070mxge_choose_params(int mtu, int *big_buf_size, int *cl_size, int *nbufs)
3071{
3072 int bufsize = mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN + MXGEFW_PAD;
3073
3074 if (bufsize < MCLBYTES) {
3075 /* easy, everything fits in a single buffer */
3076 *big_buf_size = MCLBYTES;

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

3090 *cl_size = MJUM9BYTES;
3091 *big_buf_size = 4096;
3092 *nbufs = mtu / 4096 + 1;
3093 /* needs to be a power of two, so round up */
3094 if (*nbufs == 3)
3095 *nbufs = 4;
3096}
3097
2901static int
2902mxge_open(mxge_softc_t *sc)
3098static int
3099mxge_slice_open(struct mxge_slice_state *ss, int nbufs, int cl_size)
2903{
3100{
3101 mxge_softc_t *sc;
2904 mxge_cmd_t cmd;
3102 mxge_cmd_t cmd;
2905 int i, err, big_bytes;
2906 bus_dmamap_t map;
3103 bus_dmamap_t map;
2907 bus_addr_t bus;
2908 struct lro_entry *lro_entry;
3104 struct lro_entry *lro_entry;
3105 int err, i, slice;
2909
3106
2910 SLIST_INIT(&sc->lro_free);
2911 SLIST_INIT(&sc->lro_active);
2912
3107
3108 sc = ss->sc;
3109 slice = ss - sc->ss;
3110
3111 SLIST_INIT(&ss->lro_free);
3112 SLIST_INIT(&ss->lro_active);
3113
2913 for (i = 0; i < sc->lro_cnt; i++) {
2914 lro_entry = (struct lro_entry *)
3114 for (i = 0; i < sc->lro_cnt; i++) {
3115 lro_entry = (struct lro_entry *)
2915 malloc(sizeof (*lro_entry), M_DEVBUF, M_NOWAIT | M_ZERO);
3116 malloc(sizeof (*lro_entry), M_DEVBUF,
3117 M_NOWAIT | M_ZERO);
2916 if (lro_entry == NULL) {
2917 sc->lro_cnt = i;
2918 break;
2919 }
3118 if (lro_entry == NULL) {
3119 sc->lro_cnt = i;
3120 break;
3121 }
2920 SLIST_INSERT_HEAD(&sc->lro_free, lro_entry, next);
3122 SLIST_INSERT_HEAD(&ss->lro_free, lro_entry, next);
2921 }
3123 }
2922
2923 /* Copy the MAC address in case it was overridden */
2924 bcopy(IF_LLADDR(sc->ifp), sc->mac_addr, ETHER_ADDR_LEN);
2925
2926 err = mxge_reset(sc, 1);
2927 if (err != 0) {
2928 device_printf(sc->dev, "failed to reset\n");
2929 return EIO;
2930 }
2931
2932 mxge_choose_params(sc->ifp->if_mtu, &big_bytes,
2933 &sc->rx_big.cl_size, &sc->rx_big.nbufs);
2934
2935 cmd.data0 = sc->rx_big.nbufs;
2936 err = mxge_send_cmd(sc, MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS,
2937 &cmd);
2938 /* error is only meaningful if we're trying to set
2939 MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS > 1 */
2940 if (err && sc->rx_big.nbufs > 1) {
2941 device_printf(sc->dev,
2942 "Failed to set alway-use-n to %d\n",
2943 sc->rx_big.nbufs);
2944 return EIO;
2945 }
2946 /* get the lanai pointers to the send and receive rings */
2947
3124 /* get the lanai pointers to the send and receive rings */
3125
2948 err = mxge_send_cmd(sc, MXGEFW_CMD_GET_SEND_OFFSET, &cmd);
2949 sc->tx.lanai =
2950 (volatile mcp_kreq_ether_send_t *)(sc->sram + cmd.data0);
3126 err = 0;
3127 /* We currently only send from the first slice */
3128 if (slice == 0) {
3129 cmd.data0 = slice;
3130 err = mxge_send_cmd(sc, MXGEFW_CMD_GET_SEND_OFFSET, &cmd);
3131 ss->tx.lanai =
3132 (volatile mcp_kreq_ether_send_t *)(sc->sram + cmd.data0);
3133 }
3134 cmd.data0 = slice;
2951 err |= mxge_send_cmd(sc,
3135 err |= mxge_send_cmd(sc,
2952 MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd);
2953 sc->rx_small.lanai =
3136 MXGEFW_CMD_GET_SMALL_RX_OFFSET, &cmd);
3137 ss->rx_small.lanai =
2954 (volatile mcp_kreq_ether_recv_t *)(sc->sram + cmd.data0);
3138 (volatile mcp_kreq_ether_recv_t *)(sc->sram + cmd.data0);
3139 cmd.data0 = slice;
2955 err |= mxge_send_cmd(sc, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd);
3140 err |= mxge_send_cmd(sc, MXGEFW_CMD_GET_BIG_RX_OFFSET, &cmd);
2956 sc->rx_big.lanai =
3141 ss->rx_big.lanai =
2957 (volatile mcp_kreq_ether_recv_t *)(sc->sram + cmd.data0);
2958
2959 if (err != 0) {
2960 device_printf(sc->dev,
2961 "failed to get ring sizes or locations\n");
2962 return EIO;
2963 }
2964
2965 /* stock receive rings */
3142 (volatile mcp_kreq_ether_recv_t *)(sc->sram + cmd.data0);
3143
3144 if (err != 0) {
3145 device_printf(sc->dev,
3146 "failed to get ring sizes or locations\n");
3147 return EIO;
3148 }
3149
3150 /* stock receive rings */
2966 for (i = 0; i <= sc->rx_small.mask; i++) {
2967 map = sc->rx_small.info[i].map;
2968 err = mxge_get_buf_small(sc, map, i);
3151 for (i = 0; i <= ss->rx_small.mask; i++) {
3152 map = ss->rx_small.info[i].map;
3153 err = mxge_get_buf_small(ss, map, i);
2969 if (err) {
2970 device_printf(sc->dev, "alloced %d/%d smalls\n",
3154 if (err) {
3155 device_printf(sc->dev, "alloced %d/%d smalls\n",
2971 i, sc->rx_small.mask + 1);
2972 goto abort;
3156 i, ss->rx_small.mask + 1);
3157 return ENOMEM;
2973 }
2974 }
3158 }
3159 }
2975 for (i = 0; i <= sc->rx_big.mask; i++) {
2976 sc->rx_big.shadow[i].addr_low = 0xffffffff;
2977 sc->rx_big.shadow[i].addr_high = 0xffffffff;
3160 for (i = 0; i <= ss->rx_big.mask; i++) {
3161 ss->rx_big.shadow[i].addr_low = 0xffffffff;
3162 ss->rx_big.shadow[i].addr_high = 0xffffffff;
2978 }
3163 }
2979 for (i = 0; i <= sc->rx_big.mask; i += sc->rx_big.nbufs) {
2980 map = sc->rx_big.info[i].map;
2981 err = mxge_get_buf_big(sc, map, i);
3164 ss->rx_big.nbufs = nbufs;
3165 ss->rx_big.cl_size = cl_size;
3166 for (i = 0; i <= ss->rx_big.mask; i += ss->rx_big.nbufs) {
3167 map = ss->rx_big.info[i].map;
3168 err = mxge_get_buf_big(ss, map, i);
2982 if (err) {
2983 device_printf(sc->dev, "alloced %d/%d bigs\n",
3169 if (err) {
3170 device_printf(sc->dev, "alloced %d/%d bigs\n",
2984 i, sc->rx_big.mask + 1);
2985 goto abort;
3171 i, ss->rx_big.mask + 1);
3172 return ENOMEM;
2986 }
2987 }
3173 }
3174 }
3175 return 0;
3176}
2988
3177
3178static int
3179mxge_open(mxge_softc_t *sc)
3180{
3181 mxge_cmd_t cmd;
3182 int err, big_bytes, nbufs, slice, cl_size, i;
3183 bus_addr_t bus;
3184 volatile uint8_t *itable;
3185
3186 /* Copy the MAC address in case it was overridden */
3187 bcopy(IF_LLADDR(sc->ifp), sc->mac_addr, ETHER_ADDR_LEN);
3188
3189 err = mxge_reset(sc, 1);
3190 if (err != 0) {
3191 device_printf(sc->dev, "failed to reset\n");
3192 return EIO;
3193 }
3194
3195 if (sc->num_slices > 1) {
3196 /* setup the indirection table */
3197 cmd.data0 = sc->num_slices;
3198 err = mxge_send_cmd(sc, MXGEFW_CMD_SET_RSS_TABLE_SIZE,
3199 &cmd);
3200
3201 err |= mxge_send_cmd(sc, MXGEFW_CMD_GET_RSS_TABLE_OFFSET,
3202 &cmd);
3203 if (err != 0) {
3204 device_printf(sc->dev,
3205 "failed to setup rss tables\n");
3206 return err;
3207 }
3208
3209 /* just enable an identity mapping */
3210 itable = sc->sram + cmd.data0;
3211 for (i = 0; i < sc->num_slices; i++)
3212 itable[i] = (uint8_t)i;
3213
3214 cmd.data0 = 1;
3215 cmd.data1 = mxge_rss_hash_type;
3216 err = mxge_send_cmd(sc, MXGEFW_CMD_SET_RSS_ENABLE, &cmd);
3217 if (err != 0) {
3218 device_printf(sc->dev, "failed to enable slices\n");
3219 return err;
3220 }
3221 }
3222
3223
3224 mxge_choose_params(sc->ifp->if_mtu, &big_bytes, &cl_size, &nbufs);
3225
3226 cmd.data0 = nbufs;
3227 err = mxge_send_cmd(sc, MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS,
3228 &cmd);
3229 /* error is only meaningful if we're trying to set
3230 MXGEFW_CMD_ALWAYS_USE_N_BIG_BUFFERS > 1 */
3231 if (err && nbufs > 1) {
3232 device_printf(sc->dev,
3233 "Failed to set alway-use-n to %d\n",
3234 nbufs);
3235 return EIO;
3236 }
2989 /* Give the firmware the mtu and the big and small buffer
2990 sizes. The firmware wants the big buf size to be a power
2991 of two. Luckily, FreeBSD's clusters are powers of two */
2992 cmd.data0 = sc->ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
2993 err = mxge_send_cmd(sc, MXGEFW_CMD_SET_MTU, &cmd);
2994 cmd.data0 = MHLEN - MXGEFW_PAD;
2995 err |= mxge_send_cmd(sc, MXGEFW_CMD_SET_SMALL_BUFFER_SIZE,
2996 &cmd);
2997 cmd.data0 = big_bytes;
2998 err |= mxge_send_cmd(sc, MXGEFW_CMD_SET_BIG_BUFFER_SIZE, &cmd);
2999
3000 if (err != 0) {
3001 device_printf(sc->dev, "failed to setup params\n");
3002 goto abort;
3003 }
3004
3005 /* Now give him the pointer to the stats block */
3237 /* Give the firmware the mtu and the big and small buffer
3238 sizes. The firmware wants the big buf size to be a power
3239 of two. Luckily, FreeBSD's clusters are powers of two */
3240 cmd.data0 = sc->ifp->if_mtu + ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN;
3241 err = mxge_send_cmd(sc, MXGEFW_CMD_SET_MTU, &cmd);
3242 cmd.data0 = MHLEN - MXGEFW_PAD;
3243 err |= mxge_send_cmd(sc, MXGEFW_CMD_SET_SMALL_BUFFER_SIZE,
3244 &cmd);
3245 cmd.data0 = big_bytes;
3246 err |= mxge_send_cmd(sc, MXGEFW_CMD_SET_BIG_BUFFER_SIZE, &cmd);
3247
3248 if (err != 0) {
3249 device_printf(sc->dev, "failed to setup params\n");
3250 goto abort;
3251 }
3252
3253 /* Now give him the pointer to the stats block */
3006 cmd.data0 = MXGE_LOWPART_TO_U32(sc->fw_stats_dma.bus_addr);
3007 cmd.data1 = MXGE_HIGHPART_TO_U32(sc->fw_stats_dma.bus_addr);
3254 cmd.data0 = MXGE_LOWPART_TO_U32(sc->ss->fw_stats_dma.bus_addr);
3255 cmd.data1 = MXGE_HIGHPART_TO_U32(sc->ss->fw_stats_dma.bus_addr);
3008 cmd.data2 = sizeof(struct mcp_irq_data);
3009 err = mxge_send_cmd(sc, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd);
3010
3011 if (err != 0) {
3256 cmd.data2 = sizeof(struct mcp_irq_data);
3257 err = mxge_send_cmd(sc, MXGEFW_CMD_SET_STATS_DMA_V2, &cmd);
3258
3259 if (err != 0) {
3012 bus = sc->fw_stats_dma.bus_addr;
3260 bus = sc->ss->fw_stats_dma.bus_addr;
3013 bus += offsetof(struct mcp_irq_data, send_done_count);
3014 cmd.data0 = MXGE_LOWPART_TO_U32(bus);
3015 cmd.data1 = MXGE_HIGHPART_TO_U32(bus);
3016 err = mxge_send_cmd(sc,
3017 MXGEFW_CMD_SET_STATS_DMA_OBSOLETE,
3018 &cmd);
3019 /* Firmware cannot support multicast without STATS_DMA_V2 */
3020 sc->fw_multicast_support = 0;
3021 } else {
3022 sc->fw_multicast_support = 1;
3023 }
3024
3025 if (err != 0) {
3026 device_printf(sc->dev, "failed to setup params\n");
3027 goto abort;
3028 }
3029
3261 bus += offsetof(struct mcp_irq_data, send_done_count);
3262 cmd.data0 = MXGE_LOWPART_TO_U32(bus);
3263 cmd.data1 = MXGE_HIGHPART_TO_U32(bus);
3264 err = mxge_send_cmd(sc,
3265 MXGEFW_CMD_SET_STATS_DMA_OBSOLETE,
3266 &cmd);
3267 /* Firmware cannot support multicast without STATS_DMA_V2 */
3268 sc->fw_multicast_support = 0;
3269 } else {
3270 sc->fw_multicast_support = 1;
3271 }
3272
3273 if (err != 0) {
3274 device_printf(sc->dev, "failed to setup params\n");
3275 goto abort;
3276 }
3277
3278 for (slice = 0; slice < sc->num_slices; slice++) {
3279 err = mxge_slice_open(&sc->ss[slice], nbufs, cl_size);
3280 if (err != 0) {
3281 device_printf(sc->dev, "couldn't open slice %d\n",
3282 slice);
3283 goto abort;
3284 }
3285 }
3286
3030 /* Finally, start the firmware running */
3031 err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_UP, &cmd);
3032 if (err) {
3033 device_printf(sc->dev, "Couldn't bring up link\n");
3034 goto abort;
3035 }
3036 sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
3037 sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;

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

3043 mxge_free_mbufs(sc);
3044
3045 return err;
3046}
3047
3048static int
3049mxge_close(mxge_softc_t *sc)
3050{
3287 /* Finally, start the firmware running */
3288 err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_UP, &cmd);
3289 if (err) {
3290 device_printf(sc->dev, "Couldn't bring up link\n");
3291 goto abort;
3292 }
3293 sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
3294 sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;

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

3300 mxge_free_mbufs(sc);
3301
3302 return err;
3303}
3304
3305static int
3306mxge_close(mxge_softc_t *sc)
3307{
3051 struct lro_entry *lro_entry;
3052 mxge_cmd_t cmd;
3053 int err, old_down_cnt;
3054
3055 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
3056 old_down_cnt = sc->down_cnt;
3057 mb();
3058 err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_DOWN, &cmd);
3059 if (err) {
3060 device_printf(sc->dev, "Couldn't bring down link\n");
3061 }
3062 if (old_down_cnt == sc->down_cnt) {
3063 /* wait for down irq */
3064 DELAY(10 * sc->intr_coal_delay);
3065 }
3308 mxge_cmd_t cmd;
3309 int err, old_down_cnt;
3310
3311 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
3312 old_down_cnt = sc->down_cnt;
3313 mb();
3314 err = mxge_send_cmd(sc, MXGEFW_CMD_ETHERNET_DOWN, &cmd);
3315 if (err) {
3316 device_printf(sc->dev, "Couldn't bring down link\n");
3317 }
3318 if (old_down_cnt == sc->down_cnt) {
3319 /* wait for down irq */
3320 DELAY(10 * sc->intr_coal_delay);
3321 }
3322 mb();
3066 if (old_down_cnt == sc->down_cnt) {
3067 device_printf(sc->dev, "never got down irq\n");
3068 }
3069
3070 mxge_free_mbufs(sc);
3071
3323 if (old_down_cnt == sc->down_cnt) {
3324 device_printf(sc->dev, "never got down irq\n");
3325 }
3326
3327 mxge_free_mbufs(sc);
3328
3072 while (!SLIST_EMPTY(&sc->lro_free)) {
3073 lro_entry = SLIST_FIRST(&sc->lro_free);
3074 SLIST_REMOVE_HEAD(&sc->lro_free, next);
3075 }
3076 return 0;
3077}
3078
3079static void
3080mxge_setup_cfg_space(mxge_softc_t *sc)
3081{
3082 device_t dev = sc->dev;
3083 int reg;

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

3161 /* XXXX waiting for pci_cfg_restore() to be exported */
3162 goto abort; /* just abort for now */
3163
3164 /* and redo any changes we made to our config space */
3165 mxge_setup_cfg_space(sc);
3166 } else {
3167 device_printf(sc->dev, "NIC did not reboot, ring state:\n");
3168 device_printf(sc->dev, "tx.req=%d tx.done=%d\n",
3329 return 0;
3330}
3331
3332static void
3333mxge_setup_cfg_space(mxge_softc_t *sc)
3334{
3335 device_t dev = sc->dev;
3336 int reg;

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

3414 /* XXXX waiting for pci_cfg_restore() to be exported */
3415 goto abort; /* just abort for now */
3416
3417 /* and redo any changes we made to our config space */
3418 mxge_setup_cfg_space(sc);
3419 } else {
3420 device_printf(sc->dev, "NIC did not reboot, ring state:\n");
3421 device_printf(sc->dev, "tx.req=%d tx.done=%d\n",
3169 sc->tx.req, sc->tx.done);
3422 sc->ss->tx.req, sc->ss->tx.done);
3170 device_printf(sc->dev, "pkt_done=%d fw=%d\n",
3423 device_printf(sc->dev, "pkt_done=%d fw=%d\n",
3171 sc->tx.pkt_done,
3172 be32toh(sc->fw_stats->send_done_count));
3424 sc->ss->tx.pkt_done,
3425 be32toh(sc->ss->fw_stats->send_done_count));
3173 }
3174
3175 if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
3176 mxge_close(sc);
3177 err = mxge_open(sc);
3178 }
3179
3180abort:

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

3185 if (err != 0) {
3186 callout_stop(&sc->co_hdl);
3187 }
3188}
3189
3190static void
3191mxge_watchdog(mxge_softc_t *sc)
3192{
3426 }
3427
3428 if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING) {
3429 mxge_close(sc);
3430 err = mxge_open(sc);
3431 }
3432
3433abort:

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

3438 if (err != 0) {
3439 callout_stop(&sc->co_hdl);
3440 }
3441}
3442
3443static void
3444mxge_watchdog(mxge_softc_t *sc)
3445{
3193 mxge_tx_buf_t *tx = &sc->tx;
3194 uint32_t rx_pause = be32toh(sc->fw_stats->dropped_pause);
3446 mxge_tx_ring_t *tx = &sc->ss->tx;
3447 uint32_t rx_pause = be32toh(sc->ss->fw_stats->dropped_pause);
3195
3196 /* see if we have outstanding transmits, which
3197 have been pending for more than mxge_ticks */
3198 if (tx->req != tx->done &&
3199 tx->watchdog_req != tx->watchdog_done &&
3200 tx->done == tx->watchdog_done) {
3201 /* check for pause blocking before resetting */
3202 if (tx->watchdog_rx_pause == rx_pause)

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

3210 tx->watchdog_done = tx->done;
3211 tx->watchdog_rx_pause = rx_pause;
3212
3213 if (sc->need_media_probe)
3214 mxge_media_probe(sc);
3215}
3216
3217static void
3448
3449 /* see if we have outstanding transmits, which
3450 have been pending for more than mxge_ticks */
3451 if (tx->req != tx->done &&
3452 tx->watchdog_req != tx->watchdog_done &&
3453 tx->done == tx->watchdog_done) {
3454 /* check for pause blocking before resetting */
3455 if (tx->watchdog_rx_pause == rx_pause)

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

3463 tx->watchdog_done = tx->done;
3464 tx->watchdog_rx_pause = rx_pause;
3465
3466 if (sc->need_media_probe)
3467 mxge_media_probe(sc);
3468}
3469
3470static void
3471mxge_update_stats(mxge_softc_t *sc)
3472{
3473 struct mxge_slice_state *ss;
3474 u_long ipackets = 0;
3475 int slice;
3476
3477 for(slice = 0; slice < sc->num_slices; slice++) {
3478 ss = &sc->ss[slice];
3479 ipackets += ss->ipackets;
3480 }
3481 sc->ifp->if_ipackets = ipackets;
3482
3483}
3484static void
3218mxge_tick(void *arg)
3219{
3220 mxge_softc_t *sc = arg;
3221
3222
3223 /* Synchronize with possible callout reset/stop. */
3224 if (callout_pending(&sc->co_hdl) ||
3225 !callout_active(&sc->co_hdl)) {
3226 mtx_unlock(&sc->driver_mtx);
3227 return;
3228 }
3229
3485mxge_tick(void *arg)
3486{
3487 mxge_softc_t *sc = arg;
3488
3489
3490 /* Synchronize with possible callout reset/stop. */
3491 if (callout_pending(&sc->co_hdl) ||
3492 !callout_active(&sc->co_hdl)) {
3493 mtx_unlock(&sc->driver_mtx);
3494 return;
3495 }
3496
3497 /* aggregate stats from different slices */
3498 mxge_update_stats(sc);
3499
3230 callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
3500 callout_reset(&sc->co_hdl, mxge_ticks, mxge_tick, sc);
3231 mxge_watchdog(sc);
3501 if (!sc->watchdog_countdown) {
3502 mxge_watchdog(sc);
3503 sc->watchdog_countdown = 4;
3504 }
3505 sc->watchdog_countdown--;
3232}
3233
3234static int
3235mxge_media_change(struct ifnet *ifp)
3236{
3237 return EINVAL;
3238}
3239

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

3309 /* take care of promis can allmulti
3310 flag chages */
3311 mxge_change_promisc(sc,
3312 ifp->if_flags & IFF_PROMISC);
3313 mxge_set_multicast_list(sc);
3314 }
3315 } else {
3316 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
3506}
3507
3508static int
3509mxge_media_change(struct ifnet *ifp)
3510{
3511 return EINVAL;
3512}
3513

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

3583 /* take care of promis can allmulti
3584 flag chages */
3585 mxge_change_promisc(sc,
3586 ifp->if_flags & IFF_PROMISC);
3587 mxge_set_multicast_list(sc);
3588 }
3589 } else {
3590 if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
3317 mxge_close(sc);
3318 callout_stop(&sc->co_hdl);
3591 callout_stop(&sc->co_hdl);
3592 mxge_close(sc);
3319 }
3320 }
3321 mtx_unlock(&sc->driver_mtx);
3322 break;
3323
3324 case SIOCADDMULTI:
3325 case SIOCDELMULTI:
3326 mtx_lock(&sc->driver_mtx);

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

3384 err = ENOTTY;
3385 }
3386 return err;
3387}
3388
3389static void
3390mxge_fetch_tunables(mxge_softc_t *sc)
3391{
3593 }
3594 }
3595 mtx_unlock(&sc->driver_mtx);
3596 break;
3597
3598 case SIOCADDMULTI:
3599 case SIOCDELMULTI:
3600 mtx_lock(&sc->driver_mtx);

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

3658 err = ENOTTY;
3659 }
3660 return err;
3661}
3662
3663static void
3664mxge_fetch_tunables(mxge_softc_t *sc)
3665{
3392
3666
3667 TUNABLE_INT_FETCH("hw.mxge.max_slices", &mxge_max_slices);
3393 TUNABLE_INT_FETCH("hw.mxge.flow_control_enabled",
3394 &mxge_flow_control);
3395 TUNABLE_INT_FETCH("hw.mxge.intr_coal_delay",
3396 &mxge_intr_coal_delay);
3397 TUNABLE_INT_FETCH("hw.mxge.nvidia_ecrc_enable",
3398 &mxge_nvidia_ecrc_enable);
3399 TUNABLE_INT_FETCH("hw.mxge.force_firmware",
3400 &mxge_force_firmware);
3401 TUNABLE_INT_FETCH("hw.mxge.deassert_wait",
3402 &mxge_deassert_wait);
3403 TUNABLE_INT_FETCH("hw.mxge.verbose",
3404 &mxge_verbose);
3405 TUNABLE_INT_FETCH("hw.mxge.ticks", &mxge_ticks);
3406 TUNABLE_INT_FETCH("hw.mxge.lro_cnt", &sc->lro_cnt);
3668 TUNABLE_INT_FETCH("hw.mxge.flow_control_enabled",
3669 &mxge_flow_control);
3670 TUNABLE_INT_FETCH("hw.mxge.intr_coal_delay",
3671 &mxge_intr_coal_delay);
3672 TUNABLE_INT_FETCH("hw.mxge.nvidia_ecrc_enable",
3673 &mxge_nvidia_ecrc_enable);
3674 TUNABLE_INT_FETCH("hw.mxge.force_firmware",
3675 &mxge_force_firmware);
3676 TUNABLE_INT_FETCH("hw.mxge.deassert_wait",
3677 &mxge_deassert_wait);
3678 TUNABLE_INT_FETCH("hw.mxge.verbose",
3679 &mxge_verbose);
3680 TUNABLE_INT_FETCH("hw.mxge.ticks", &mxge_ticks);
3681 TUNABLE_INT_FETCH("hw.mxge.lro_cnt", &sc->lro_cnt);
3682 TUNABLE_INT_FETCH("hw.mxge.always_promisc", &mxge_always_promisc);
3683 TUNABLE_INT_FETCH("hw.mxge.rss_hash_type", &mxge_rss_hash_type);
3407 if (sc->lro_cnt != 0)
3408 mxge_lro_cnt = sc->lro_cnt;
3409
3410 if (bootverbose)
3411 mxge_verbose = 1;
3412 if (mxge_intr_coal_delay < 0 || mxge_intr_coal_delay > 10*1000)
3413 mxge_intr_coal_delay = 30;
3414 if (mxge_ticks == 0)
3684 if (sc->lro_cnt != 0)
3685 mxge_lro_cnt = sc->lro_cnt;
3686
3687 if (bootverbose)
3688 mxge_verbose = 1;
3689 if (mxge_intr_coal_delay < 0 || mxge_intr_coal_delay > 10*1000)
3690 mxge_intr_coal_delay = 30;
3691 if (mxge_ticks == 0)
3415 mxge_ticks = hz;
3692 mxge_ticks = hz / 2;
3416 sc->pause = mxge_flow_control;
3693 sc->pause = mxge_flow_control;
3694 if (mxge_rss_hash_type < MXGEFW_RSS_HASH_TYPE_IPV4
3695 || mxge_rss_hash_type > MXGEFW_RSS_HASH_TYPE_SRC_PORT) {
3696 mxge_rss_hash_type = MXGEFW_RSS_HASH_TYPE_SRC_PORT;
3697 }
3698}
3417
3699
3700
3701static void
3702mxge_free_slices(mxge_softc_t *sc)
3703{
3704 struct mxge_slice_state *ss;
3705 int i;
3706
3707
3708 if (sc->ss == NULL)
3709 return;
3710
3711 for (i = 0; i < sc->num_slices; i++) {
3712 ss = &sc->ss[i];
3713 if (ss->fw_stats != NULL) {
3714 mxge_dma_free(&ss->fw_stats_dma);
3715 ss->fw_stats = NULL;
3716 mtx_destroy(&ss->tx.mtx);
3717 }
3718 if (ss->rx_done.entry != NULL) {
3719 mxge_dma_free(&ss->rx_done.dma);
3720 ss->rx_done.entry = NULL;
3721 }
3722 }
3723 free(sc->ss, M_DEVBUF);
3724 sc->ss = NULL;
3418}
3419
3725}
3726
3727static int
3728mxge_alloc_slices(mxge_softc_t *sc)
3729{
3730 mxge_cmd_t cmd;
3731 struct mxge_slice_state *ss;
3732 size_t bytes;
3733 int err, i, max_intr_slots;
3734
3735 err = mxge_send_cmd(sc, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd);
3736 if (err != 0) {
3737 device_printf(sc->dev, "Cannot determine rx ring size\n");
3738 return err;
3739 }
3740 sc->rx_ring_size = cmd.data0;
3741 max_intr_slots = 2 * (sc->rx_ring_size / sizeof (mcp_dma_addr_t));
3742
3743 bytes = sizeof (*sc->ss) * sc->num_slices;
3744 sc->ss = malloc(bytes, M_DEVBUF, M_NOWAIT | M_ZERO);
3745 if (sc->ss == NULL)
3746 return (ENOMEM);
3747 for (i = 0; i < sc->num_slices; i++) {
3748 ss = &sc->ss[i];
3749
3750 ss->sc = sc;
3751
3752 /* allocate per-slice rx interrupt queues */
3753
3754 bytes = max_intr_slots * sizeof (*ss->rx_done.entry);
3755 err = mxge_dma_alloc(sc, &ss->rx_done.dma, bytes, 4096);
3756 if (err != 0)
3757 goto abort;
3758 ss->rx_done.entry = ss->rx_done.dma.addr;
3759 bzero(ss->rx_done.entry, bytes);
3760
3761 /*
3762 * allocate the per-slice firmware stats; stats
3763 * (including tx) are used used only on the first
3764 * slice for now
3765 */
3766 if (i > 0)
3767 continue;
3768
3769 bytes = sizeof (*ss->fw_stats);
3770 err = mxge_dma_alloc(sc, &ss->fw_stats_dma,
3771 sizeof (*ss->fw_stats), 64);
3772 if (err != 0)
3773 goto abort;
3774 ss->fw_stats = (mcp_irq_data_t *)ss->fw_stats_dma.addr;
3775 snprintf(ss->tx.mtx_name, sizeof(ss->tx.mtx_name),
3776 "%s:tx(%d)", device_get_nameunit(sc->dev), i);
3777 mtx_init(&ss->tx.mtx, ss->tx.mtx_name, NULL, MTX_DEF);
3778 }
3779
3780 return (0);
3781
3782abort:
3783 mxge_free_slices(sc);
3784 return (ENOMEM);
3785}
3786
3787static void
3788mxge_slice_probe(mxge_softc_t *sc)
3789{
3790 mxge_cmd_t cmd;
3791 char *old_fw;
3792 int msix_cnt, status, max_intr_slots;
3793
3794 sc->num_slices = 1;
3795 /*
3796 * don't enable multiple slices if they are not enabled,
3797 * or if this is not an SMP system
3798 */
3799
3800 if (mxge_max_slices == 0 || mxge_max_slices == 1 || mp_ncpus < 2)
3801 return;
3802
3803 /* see how many MSI-X interrupts are available */
3804 msix_cnt = pci_msix_count(sc->dev);
3805 if (msix_cnt < 2)
3806 return;
3807
3808 /* now load the slice aware firmware see what it supports */
3809 old_fw = sc->fw_name;
3810 if (old_fw == mxge_fw_aligned)
3811 sc->fw_name = mxge_fw_rss_aligned;
3812 else
3813 sc->fw_name = mxge_fw_rss_unaligned;
3814 status = mxge_load_firmware(sc, 0);
3815 if (status != 0) {
3816 device_printf(sc->dev, "Falling back to a single slice\n");
3817 return;
3818 }
3819
3820 /* try to send a reset command to the card to see if it
3821 is alive */
3822 memset(&cmd, 0, sizeof (cmd));
3823 status = mxge_send_cmd(sc, MXGEFW_CMD_RESET, &cmd);
3824 if (status != 0) {
3825 device_printf(sc->dev, "failed reset\n");
3826 goto abort_with_fw;
3827 }
3828
3829 /* get rx ring size */
3830 status = mxge_send_cmd(sc, MXGEFW_CMD_GET_RX_RING_SIZE, &cmd);
3831 if (status != 0) {
3832 device_printf(sc->dev, "Cannot determine rx ring size\n");
3833 goto abort_with_fw;
3834 }
3835 max_intr_slots = 2 * (cmd.data0 / sizeof (mcp_dma_addr_t));
3836
3837 /* tell it the size of the interrupt queues */
3838 cmd.data0 = max_intr_slots * sizeof (struct mcp_slot);
3839 status = mxge_send_cmd(sc, MXGEFW_CMD_SET_INTRQ_SIZE, &cmd);
3840 if (status != 0) {
3841 device_printf(sc->dev, "failed MXGEFW_CMD_SET_INTRQ_SIZE\n");
3842 goto abort_with_fw;
3843 }
3844
3845 /* ask the maximum number of slices it supports */
3846 status = mxge_send_cmd(sc, MXGEFW_CMD_GET_MAX_RSS_QUEUES, &cmd);
3847 if (status != 0) {
3848 device_printf(sc->dev,
3849 "failed MXGEFW_CMD_GET_MAX_RSS_QUEUES\n");
3850 goto abort_with_fw;
3851 }
3852 sc->num_slices = cmd.data0;
3853 if (sc->num_slices > msix_cnt)
3854 sc->num_slices = msix_cnt;
3855
3856 if (mxge_max_slices == -1) {
3857 /* cap to number of CPUs in system */
3858 if (sc->num_slices > mp_ncpus)
3859 sc->num_slices = mp_ncpus;
3860 } else {
3861 if (sc->num_slices > mxge_max_slices)
3862 sc->num_slices = mxge_max_slices;
3863 }
3864 /* make sure it is a power of two */
3865 while (sc->num_slices & (sc->num_slices - 1))
3866 sc->num_slices--;
3867
3868 if (mxge_verbose)
3869 device_printf(sc->dev, "using %d slices\n",
3870 sc->num_slices);
3871
3872 return;
3873
3874abort_with_fw:
3875 sc->fw_name = old_fw;
3876 (void) mxge_load_firmware(sc, 0);
3877}
3878
3879static int
3880mxge_add_msix_irqs(mxge_softc_t *sc)
3881{
3882 size_t bytes;
3883 int count, err, i, rid;
3884
3885 rid = PCIR_BAR(2);
3886 sc->msix_table_res = bus_alloc_resource_any(sc->dev, SYS_RES_MEMORY,
3887 &rid, RF_ACTIVE);
3888
3889 if (sc->msix_table_res == NULL) {
3890 device_printf(sc->dev, "couldn't alloc MSIX table res\n");
3891 return ENXIO;
3892 }
3893
3894 count = sc->num_slices;
3895 err = pci_alloc_msix(sc->dev, &count);
3896 if (err != 0) {
3897 device_printf(sc->dev, "pci_alloc_msix: failed, wanted %d"
3898 "err = %d \n", sc->num_slices, err);
3899 goto abort_with_msix_table;
3900 }
3901 if (count < sc->num_slices) {
3902 device_printf(sc->dev, "pci_alloc_msix: need %d, got %d\n",
3903 count, sc->num_slices);
3904 device_printf(sc->dev,
3905 "Try setting hw.mxge.max_slices to %d\n",
3906 count);
3907 err = ENOSPC;
3908 goto abort_with_msix;
3909 }
3910 bytes = sizeof (*sc->msix_irq_res) * sc->num_slices;
3911 sc->msix_irq_res = malloc(bytes, M_DEVBUF, M_NOWAIT|M_ZERO);
3912 if (sc->msix_irq_res == NULL) {
3913 err = ENOMEM;
3914 goto abort_with_msix;
3915 }
3916
3917 for (i = 0; i < sc->num_slices; i++) {
3918 rid = i + 1;
3919 sc->msix_irq_res[i] = bus_alloc_resource_any(sc->dev,
3920 SYS_RES_IRQ,
3921 &rid, RF_ACTIVE);
3922 if (sc->msix_irq_res[i] == NULL) {
3923 device_printf(sc->dev, "couldn't allocate IRQ res"
3924 " for message %d\n", i);
3925 err = ENXIO;
3926 goto abort_with_res;
3927 }
3928 }
3929
3930 bytes = sizeof (*sc->msix_ih) * sc->num_slices;
3931 sc->msix_ih = malloc(bytes, M_DEVBUF, M_NOWAIT|M_ZERO);
3932
3933 for (i = 0; i < sc->num_slices; i++) {
3934 err = bus_setup_intr(sc->dev, sc->msix_irq_res[i],
3935 INTR_TYPE_NET | INTR_MPSAFE,
3936 NULL, mxge_intr, &sc->ss[i],
3937 &sc->msix_ih[i]);
3938 if (err != 0) {
3939 device_printf(sc->dev, "couldn't setup intr for "
3940 "message %d\n", i);
3941 goto abort_with_intr;
3942 }
3943 }
3944
3945 if (mxge_verbose) {
3946 device_printf(sc->dev, "using %d msix IRQs:",
3947 sc->num_slices);
3948 for (i = 0; i < sc->num_slices; i++)
3949 printf(" %ld", rman_get_start(sc->msix_irq_res[i]));
3950 printf("\n");
3951 }
3952 return (0);
3953
3954abort_with_intr:
3955 for (i = 0; i < sc->num_slices; i++) {
3956 if (sc->msix_ih[i] != NULL) {
3957 bus_teardown_intr(sc->dev, sc->msix_irq_res[i],
3958 sc->msix_ih[i]);
3959 sc->msix_ih[i] = NULL;
3960 }
3961 }
3962 free(sc->msix_ih, M_DEVBUF);
3963
3964
3965abort_with_res:
3966 for (i = 0; i < sc->num_slices; i++) {
3967 rid = i + 1;
3968 if (sc->msix_irq_res[i] != NULL)
3969 bus_release_resource(sc->dev, SYS_RES_IRQ, rid,
3970 sc->msix_irq_res[i]);
3971 sc->msix_irq_res[i] = NULL;
3972 }
3973 free(sc->msix_irq_res, M_DEVBUF);
3974
3975
3976abort_with_msix:
3977 pci_release_msi(sc->dev);
3978
3979abort_with_msix_table:
3980 bus_release_resource(sc->dev, SYS_RES_MEMORY, PCIR_BAR(2),
3981 sc->msix_table_res);
3982
3983 return err;
3984}
3985
3986static int
3987mxge_add_single_irq(mxge_softc_t *sc)
3988{
3989 int count, err, rid;
3990
3991 count = pci_msi_count(sc->dev);
3992 if (count == 1 && pci_alloc_msi(sc->dev, &count) == 0) {
3993 rid = 1;
3994 sc->msi_enabled = 1;
3995 } else {
3996 rid = 0;
3997 }
3998 sc->irq_res = bus_alloc_resource(sc->dev, SYS_RES_IRQ, &rid, 0, ~0,
3999 1, RF_SHAREABLE | RF_ACTIVE);
4000 if (sc->irq_res == NULL) {
4001 device_printf(sc->dev, "could not alloc interrupt\n");
4002 return ENXIO;
4003 }
4004 if (mxge_verbose)
4005 device_printf(sc->dev, "using %s irq %ld\n",
4006 sc->msi_enabled ? "MSI" : "INTx",
4007 rman_get_start(sc->irq_res));
4008 err = bus_setup_intr(sc->dev, sc->irq_res,
4009 INTR_TYPE_NET | INTR_MPSAFE,
4010 NULL, mxge_intr, &sc->ss[0], &sc->ih);
4011 if (err != 0) {
4012 bus_release_resource(sc->dev, SYS_RES_IRQ,
4013 sc->msi_enabled ? 1 : 0, sc->irq_res);
4014 if (sc->msi_enabled)
4015 pci_release_msi(sc->dev);
4016 }
4017 return err;
4018}
4019
4020static void
4021mxge_rem_msix_irqs(mxge_softc_t *sc)
4022{
4023 int i, rid;
4024
4025 for (i = 0; i < sc->num_slices; i++) {
4026 if (sc->msix_ih[i] != NULL) {
4027 bus_teardown_intr(sc->dev, sc->msix_irq_res[i],
4028 sc->msix_ih[i]);
4029 sc->msix_ih[i] = NULL;
4030 }
4031 }
4032 free(sc->msix_ih, M_DEVBUF);
4033
4034 for (i = 0; i < sc->num_slices; i++) {
4035 rid = i + 1;
4036 if (sc->msix_irq_res[i] != NULL)
4037 bus_release_resource(sc->dev, SYS_RES_IRQ, rid,
4038 sc->msix_irq_res[i]);
4039 sc->msix_irq_res[i] = NULL;
4040 }
4041 free(sc->msix_irq_res, M_DEVBUF);
4042
4043 bus_release_resource(sc->dev, SYS_RES_MEMORY, PCIR_BAR(2),
4044 sc->msix_table_res);
4045
4046 pci_release_msi(sc->dev);
4047 return;
4048}
4049
4050static void
4051mxge_rem_single_irq(mxge_softc_t *sc)
4052{
4053 bus_teardown_intr(sc->dev, sc->irq_res, sc->ih);
4054 bus_release_resource(sc->dev, SYS_RES_IRQ,
4055 sc->msi_enabled ? 1 : 0, sc->irq_res);
4056 if (sc->msi_enabled)
4057 pci_release_msi(sc->dev);
4058}
4059
4060static void
4061mxge_rem_irq(mxge_softc_t *sc)
4062{
4063 if (sc->num_slices > 1)
4064 mxge_rem_msix_irqs(sc);
4065 else
4066 mxge_rem_single_irq(sc);
4067}
4068
4069static int
4070mxge_add_irq(mxge_softc_t *sc)
4071{
4072 int err;
4073
4074 if (sc->num_slices > 1)
4075 err = mxge_add_msix_irqs(sc);
4076 else
4077 err = mxge_add_single_irq(sc);
4078
4079 if (0 && err == 0 && sc->num_slices > 1) {
4080 mxge_rem_msix_irqs(sc);
4081 err = mxge_add_msix_irqs(sc);
4082 }
4083 return err;
4084}
4085
4086
3420static int
3421mxge_attach(device_t dev)
3422{
3423 mxge_softc_t *sc = device_get_softc(dev);
3424 struct ifnet *ifp;
4087static int
4088mxge_attach(device_t dev)
4089{
4090 mxge_softc_t *sc = device_get_softc(dev);
4091 struct ifnet *ifp;
3425 int count, rid, err;
4092 int err, rid;
3426
3427 sc->dev = dev;
3428 mxge_fetch_tunables(sc);
3429
3430 err = bus_dma_tag_create(NULL, /* parent */
3431 1, /* alignment */
4093
4094 sc->dev = dev;
4095 mxge_fetch_tunables(sc);
4096
4097 err = bus_dma_tag_create(NULL, /* parent */
4098 1, /* alignment */
3432 4096, /* boundary */
4099 0, /* boundary */
3433 BUS_SPACE_MAXADDR, /* low */
3434 BUS_SPACE_MAXADDR, /* high */
3435 NULL, NULL, /* filter */
3436 65536 + 256, /* maxsize */
3437 MXGE_MAX_SEND_DESC, /* num segs */
4100 BUS_SPACE_MAXADDR, /* low */
4101 BUS_SPACE_MAXADDR, /* high */
4102 NULL, NULL, /* filter */
4103 65536 + 256, /* maxsize */
4104 MXGE_MAX_SEND_DESC, /* num segs */
3438 4096, /* maxsegsize */
4105 65536, /* maxsegsize */
3439 0, /* flags */
3440 NULL, NULL, /* lock */
3441 &sc->parent_dmat); /* tag */
3442
3443 if (err != 0) {
3444 device_printf(sc->dev, "Err %d allocating parent dmat\n",
3445 err);
3446 goto abort_with_nothing;
3447 }
3448
3449 ifp = sc->ifp = if_alloc(IFT_ETHER);
3450 if (ifp == NULL) {
3451 device_printf(dev, "can not if_alloc()\n");
3452 err = ENOSPC;
3453 goto abort_with_parent_dmat;
3454 }
4106 0, /* flags */
4107 NULL, NULL, /* lock */
4108 &sc->parent_dmat); /* tag */
4109
4110 if (err != 0) {
4111 device_printf(sc->dev, "Err %d allocating parent dmat\n",
4112 err);
4113 goto abort_with_nothing;
4114 }
4115
4116 ifp = sc->ifp = if_alloc(IFT_ETHER);
4117 if (ifp == NULL) {
4118 device_printf(dev, "can not if_alloc()\n");
4119 err = ENOSPC;
4120 goto abort_with_parent_dmat;
4121 }
4122 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
4123
3455 snprintf(sc->cmd_mtx_name, sizeof(sc->cmd_mtx_name), "%s:cmd",
3456 device_get_nameunit(dev));
3457 mtx_init(&sc->cmd_mtx, sc->cmd_mtx_name, NULL, MTX_DEF);
4124 snprintf(sc->cmd_mtx_name, sizeof(sc->cmd_mtx_name), "%s:cmd",
4125 device_get_nameunit(dev));
4126 mtx_init(&sc->cmd_mtx, sc->cmd_mtx_name, NULL, MTX_DEF);
3458 snprintf(sc->tx_mtx_name, sizeof(sc->tx_mtx_name), "%s:tx",
3459 device_get_nameunit(dev));
3460 mtx_init(&sc->tx_mtx, sc->tx_mtx_name, NULL, MTX_DEF);
3461 snprintf(sc->driver_mtx_name, sizeof(sc->driver_mtx_name),
3462 "%s:drv", device_get_nameunit(dev));
3463 mtx_init(&sc->driver_mtx, sc->driver_mtx_name,
3464 MTX_NETWORK_LOCK, MTX_DEF);
3465
3466 callout_init_mtx(&sc->co_hdl, &sc->driver_mtx, 0);
3467
3468 mxge_setup_cfg_space(sc);

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

3505 sizeof (mxge_cmd_t), 64);
3506 if (err != 0)
3507 goto abort_with_mem_res;
3508 sc->cmd = (mcp_cmd_response_t *) sc->cmd_dma.addr;
3509 err = mxge_dma_alloc(sc, &sc->zeropad_dma, 64, 64);
3510 if (err != 0)
3511 goto abort_with_cmd_dma;
3512
4127 snprintf(sc->driver_mtx_name, sizeof(sc->driver_mtx_name),
4128 "%s:drv", device_get_nameunit(dev));
4129 mtx_init(&sc->driver_mtx, sc->driver_mtx_name,
4130 MTX_NETWORK_LOCK, MTX_DEF);
4131
4132 callout_init_mtx(&sc->co_hdl, &sc->driver_mtx, 0);
4133
4134 mxge_setup_cfg_space(sc);

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

4171 sizeof (mxge_cmd_t), 64);
4172 if (err != 0)
4173 goto abort_with_mem_res;
4174 sc->cmd = (mcp_cmd_response_t *) sc->cmd_dma.addr;
4175 err = mxge_dma_alloc(sc, &sc->zeropad_dma, 64, 64);
4176 if (err != 0)
4177 goto abort_with_cmd_dma;
4178
3513 err = mxge_dma_alloc(sc, &sc->fw_stats_dma,
3514 sizeof (*sc->fw_stats), 64);
3515 if (err != 0)
3516 goto abort_with_zeropad_dma;
3517 sc->fw_stats = (mcp_irq_data_t *)sc->fw_stats_dma.addr;
3518
3519 err = mxge_dma_alloc(sc, &sc->dmabench_dma, 4096, 4096);
3520 if (err != 0)
4179 err = mxge_dma_alloc(sc, &sc->dmabench_dma, 4096, 4096);
4180 if (err != 0)
3521 goto abort_with_fw_stats;
4181 goto abort_with_zeropad_dma;
3522
4182
3523 /* Add our ithread */
3524 count = pci_msi_count(dev);
3525 if (count == 1 && pci_alloc_msi(dev, &count) == 0) {
3526 rid = 1;
3527 sc->msi_enabled = 1;
3528 } else {
3529 rid = 0;
3530 }
3531 sc->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0,
3532 1, RF_SHAREABLE | RF_ACTIVE);
3533 if (sc->irq_res == NULL) {
3534 device_printf(dev, "could not alloc interrupt\n");
3535 goto abort_with_dmabench;
3536 }
3537 if (mxge_verbose)
3538 device_printf(dev, "using %s irq %ld\n",
3539 sc->msi_enabled ? "MSI" : "INTx",
3540 rman_get_start(sc->irq_res));
3541 /* select & load the firmware */
3542 err = mxge_select_firmware(sc);
3543 if (err != 0)
4183 /* select & load the firmware */
4184 err = mxge_select_firmware(sc);
4185 if (err != 0)
3544 goto abort_with_irq_res;
4186 goto abort_with_dmabench;
3545 sc->intr_coal_delay = mxge_intr_coal_delay;
4187 sc->intr_coal_delay = mxge_intr_coal_delay;
4188
4189 mxge_slice_probe(sc);
4190 err = mxge_alloc_slices(sc);
4191 if (err != 0)
4192 goto abort_with_dmabench;
4193
3546 err = mxge_reset(sc, 0);
3547 if (err != 0)
4194 err = mxge_reset(sc, 0);
4195 if (err != 0)
3548 goto abort_with_irq_res;
4196 goto abort_with_slices;
3549
3550 err = mxge_alloc_rings(sc);
3551 if (err != 0) {
3552 device_printf(sc->dev, "failed to allocate rings\n");
4197
4198 err = mxge_alloc_rings(sc);
4199 if (err != 0) {
4200 device_printf(sc->dev, "failed to allocate rings\n");
3553 goto abort_with_irq_res;
4201 goto abort_with_dmabench;
3554 }
3555
4202 }
4203
3556 err = bus_setup_intr(sc->dev, sc->irq_res,
3557 INTR_TYPE_NET | INTR_MPSAFE,
3558 NULL, mxge_intr, sc, &sc->ih);
4204 err = mxge_add_irq(sc);
3559 if (err != 0) {
4205 if (err != 0) {
4206 device_printf(sc->dev, "failed to add irq\n");
3560 goto abort_with_rings;
3561 }
4207 goto abort_with_rings;
4208 }
3562 /* hook into the network stack */
3563 if_initname(ifp, device_get_name(dev), device_get_unit(dev));
4209
3564 ifp->if_baudrate = 100000000;
3565 ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_TSO4 |
3566 IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |
3567 IFCAP_VLAN_HWCSUM | IFCAP_LRO;
3568
3569 sc->max_mtu = mxge_max_mtu(sc);
3570 if (sc->max_mtu >= 9000)
3571 ifp->if_capabilities |= IFCAP_JUMBO_MTU;

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

3593 if (ifp->if_capabilities & IFCAP_JUMBO_MTU)
3594 ifp->if_mtu = 9000;
3595
3596 mxge_add_sysctls(sc);
3597 return 0;
3598
3599abort_with_rings:
3600 mxge_free_rings(sc);
4210 ifp->if_baudrate = 100000000;
4211 ifp->if_capabilities = IFCAP_RXCSUM | IFCAP_TXCSUM | IFCAP_TSO4 |
4212 IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING |
4213 IFCAP_VLAN_HWCSUM | IFCAP_LRO;
4214
4215 sc->max_mtu = mxge_max_mtu(sc);
4216 if (sc->max_mtu >= 9000)
4217 ifp->if_capabilities |= IFCAP_JUMBO_MTU;

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

4239 if (ifp->if_capabilities & IFCAP_JUMBO_MTU)
4240 ifp->if_mtu = 9000;
4241
4242 mxge_add_sysctls(sc);
4243 return 0;
4244
4245abort_with_rings:
4246 mxge_free_rings(sc);
3601abort_with_irq_res:
3602 bus_release_resource(dev, SYS_RES_IRQ,
3603 sc->msi_enabled ? 1 : 0, sc->irq_res);
3604 if (sc->msi_enabled)
3605 pci_release_msi(dev);
4247abort_with_slices:
4248 mxge_free_slices(sc);
3606abort_with_dmabench:
3607 mxge_dma_free(&sc->dmabench_dma);
4249abort_with_dmabench:
4250 mxge_dma_free(&sc->dmabench_dma);
3608abort_with_fw_stats:
3609 mxge_dma_free(&sc->fw_stats_dma);
3610abort_with_zeropad_dma:
3611 mxge_dma_free(&sc->zeropad_dma);
3612abort_with_cmd_dma:
3613 mxge_dma_free(&sc->cmd_dma);
3614abort_with_mem_res:
3615 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BARS, sc->mem_res);
3616abort_with_lock:
3617 pci_disable_busmaster(dev);
3618 mtx_destroy(&sc->cmd_mtx);
4251abort_with_zeropad_dma:
4252 mxge_dma_free(&sc->zeropad_dma);
4253abort_with_cmd_dma:
4254 mxge_dma_free(&sc->cmd_dma);
4255abort_with_mem_res:
4256 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BARS, sc->mem_res);
4257abort_with_lock:
4258 pci_disable_busmaster(dev);
4259 mtx_destroy(&sc->cmd_mtx);
3619 mtx_destroy(&sc->tx_mtx);
3620 mtx_destroy(&sc->driver_mtx);
3621 if_free(ifp);
3622abort_with_parent_dmat:
3623 bus_dma_tag_destroy(sc->parent_dmat);
3624
3625abort_with_nothing:
3626 return err;
3627}

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

3632 mxge_softc_t *sc = device_get_softc(dev);
3633
3634 if (sc->ifp->if_vlantrunk != NULL) {
3635 device_printf(sc->dev,
3636 "Detach vlans before removing module\n");
3637 return EBUSY;
3638 }
3639 mtx_lock(&sc->driver_mtx);
4260 mtx_destroy(&sc->driver_mtx);
4261 if_free(ifp);
4262abort_with_parent_dmat:
4263 bus_dma_tag_destroy(sc->parent_dmat);
4264
4265abort_with_nothing:
4266 return err;
4267}

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

4272 mxge_softc_t *sc = device_get_softc(dev);
4273
4274 if (sc->ifp->if_vlantrunk != NULL) {
4275 device_printf(sc->dev,
4276 "Detach vlans before removing module\n");
4277 return EBUSY;
4278 }
4279 mtx_lock(&sc->driver_mtx);
4280 callout_stop(&sc->co_hdl);
3640 if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING)
3641 mxge_close(sc);
4281 if (sc->ifp->if_drv_flags & IFF_DRV_RUNNING)
4282 mxge_close(sc);
3642 callout_stop(&sc->co_hdl);
3643 mtx_unlock(&sc->driver_mtx);
3644 ether_ifdetach(sc->ifp);
3645 ifmedia_removeall(&sc->media);
3646 mxge_dummy_rdma(sc, 0);
4283 mtx_unlock(&sc->driver_mtx);
4284 ether_ifdetach(sc->ifp);
4285 ifmedia_removeall(&sc->media);
4286 mxge_dummy_rdma(sc, 0);
3647 bus_teardown_intr(sc->dev, sc->irq_res, sc->ih);
4287 mxge_rem_sysctls(sc);
4288 mxge_rem_irq(sc);
3648 mxge_free_rings(sc);
4289 mxge_free_rings(sc);
3649 bus_release_resource(dev, SYS_RES_IRQ,
3650 sc->msi_enabled ? 1 : 0, sc->irq_res);
3651 if (sc->msi_enabled)
3652 pci_release_msi(dev);
3653
3654 sc->rx_done.entry = NULL;
3655 mxge_dma_free(&sc->fw_stats_dma);
4290 mxge_free_slices(sc);
3656 mxge_dma_free(&sc->dmabench_dma);
3657 mxge_dma_free(&sc->zeropad_dma);
3658 mxge_dma_free(&sc->cmd_dma);
3659 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BARS, sc->mem_res);
3660 pci_disable_busmaster(dev);
3661 mtx_destroy(&sc->cmd_mtx);
4291 mxge_dma_free(&sc->dmabench_dma);
4292 mxge_dma_free(&sc->zeropad_dma);
4293 mxge_dma_free(&sc->cmd_dma);
4294 bus_release_resource(dev, SYS_RES_MEMORY, PCIR_BARS, sc->mem_res);
4295 pci_disable_busmaster(dev);
4296 mtx_destroy(&sc->cmd_mtx);
3662 mtx_destroy(&sc->tx_mtx);
3663 mtx_destroy(&sc->driver_mtx);
3664 if_free(sc->ifp);
3665 bus_dma_tag_destroy(sc->parent_dmat);
3666 return 0;
3667}
3668
3669static int
3670mxge_shutdown(device_t dev)

--- 12 unchanged lines hidden ---
4297 mtx_destroy(&sc->driver_mtx);
4298 if_free(sc->ifp);
4299 bus_dma_tag_destroy(sc->parent_dmat);
4300 return 0;
4301}
4302
4303static int
4304mxge_shutdown(device_t dev)

--- 12 unchanged lines hidden ---