Lines Matching +full:magic +full:- +full:packet
1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
8 * Cambridge Computer Laboratory under DARPA/AFRL contract FA8750-11-C-0249
83 * Depending on the channel (0 if packet transaction, 1 if register transaction)
88 * (1) SUME received a packet on one of the interfaces.
89 * (2) SUME generates an interrupt vector, bit 00001 is set (channel 0 - new RX
91 * (3) We read the length of the incoming packet and the offset along with the
95 * - First 3*sizeof(uint32_t) bytes are: lower and upper 32 bits of physical
98 * - Data will start right after, at buf_addr+3*sizeof(uint32_t). The
106 * (6) SUME generates an interrupt vector, bit 00010 is set (channel 0 -
108 * (7) SUME generates an interrupt vector, bit 00100 is set (channel 0 -
116 * (11) We forward the mbuf to the appropriate interface via ifp->if_input.
120 * (2) We get the mbuf packet data and copy it to the
124 * (4) We write the offset/last and length of the packet to the SUME registers
131 * (7) SUME generates an interrupt vector, bit 01000 is set (channel 0 -
133 * (8) SUME generates an interrupt vector, bit 10000 is set (channel 0 -
169 return (bus_space_read_4(adapter->bt, adapter->bh, offset << 2));
176 bus_space_write_4(adapter->bt, adapter->bh, offset << 2, val);
200 * Building mbuf for packet received from SUME. We expect to receive 'len'
203 * received the packet (sport will be 1, 2, 4 or 8), the packet length (plen),
204 * and the magic word needs to be 0xcafe. When we have the packet data, we
216 uint16_t dport, plen, magic;
217 device_t dev = adapter->dev;
219 adapter->recv[SUME_RIFFA_CHANNEL_DATA]->buf_addr +
226 adapter->packets_err++;
227 adapter->bytes_err += len;
231 dport = le16toh(mdata->dport);
232 plen = le16toh(mdata->plen);
233 magic = le16toh(mdata->magic);
236 magic != SUME_RIFFA_MAGIC) {
237 device_printf(dev, "corrupted packet (%zd + %d > %d || magic "
239 len, magic, SUME_RIFFA_MAGIC);
243 /* We got the packet from one of the even bits */
244 np = (ffs(dport & SUME_DPORT_MASK) >> 1) - 1;
248 adapter->packets_err++;
249 adapter->bytes_err += plen;
252 ifp = adapter->ifp[np];
254 nf_priv->stats.rx_packets++;
255 nf_priv->stats.rx_bytes += plen;
259 nf_priv->stats.ifc_down_packets++;
260 nf_priv->stats.ifc_down_bytes += plen;
264 if (adapter->sume_debug)
269 adapter->packets_err++;
270 adapter->bytes_err += plen;
276 m->m_pkthdr.rcvif = ifp;
289 * bit 0 - new transaction from SUME
290 * bit 1 - SUME received our bouncebuffer address
291 * bit 2 - SUME copied the received data to our bouncebuffer, transaction done
293 * bit 3 - SUME received our bouncebuffer address
294 * bit 4 - SUME copied the data from our bouncebuffer, transaction done
305 * our packet). Then we get the length of the sent data and go back to the
322 device_t dev = adapter->dev;
341 send = adapter->send[ch];
342 recv = adapter->recv[ch];
347 if (adapter->sume_debug)
349 "0x%08x\n", ch, send->state, vect);
350 switch (send->state) {
357 "vect = 0x%08x\n", ch, send->state,
359 send->recovery = 1;
362 send->state = SUME_RIFFA_CHAN_STATE_READ;
369 "vect = 0x%08x\n", ch, send->state,
371 send->recovery = 1;
374 send->state = SUME_RIFFA_CHAN_STATE_LEN;
379 send->state =
383 wakeup(&send->event);
387 "vect = 0x%08x\n", ch, send->state,
389 send->recovery = 1;
402 send->recovery)
405 "%d\n", ch, vect, send->state, loops);
410 if (adapter->sume_debug)
412 "0x%08x\n", ch, recv->state, vect);
413 switch (recv->state) {
418 "vect = 0x%08x\n", ch, recv->state,
420 recv->recovery = 1;
426 recv->recovery = 0;
429 recv->offlast = read_reg(adapter,
432 recv->len = read_reg(adapter, RIFFA_CHNL_REG(ch,
436 max_ptr = (uint32_t)((uintptr_t)recv->buf_addr
437 + SUME_RIFFA_OFFSET(recv->offlast)
438 + SUME_RIFFA_LEN(recv->len) - 1);
440 (uint32_t)((uintptr_t)recv->buf_addr))
442 "wrap-around overflow.\n");
443 if (SUME_RIFFA_OFFSET(recv->offlast) +
444 SUME_RIFFA_LEN(recv->len) >
445 adapter->sg_buf_size)
451 SUME_RIFFA_LEN(recv->len));
453 bus_dmamap_sync(recv->ch_tag, recv->ch_map,
458 SUME_RIFFA_LO_ADDR(recv->buf_hw_addr));
461 SUME_RIFFA_HI_ADDR(recv->buf_hw_addr));
464 4 * recv->num_sg);
465 bus_dmamap_sync(recv->ch_tag, recv->ch_map,
469 recv->state = SUME_RIFFA_CHAN_STATE_READY;
476 "vect = 0x%08x\n", ch, recv->state,
478 recv->recovery = 1;
481 recv->state = SUME_RIFFA_CHAN_STATE_READ;
488 "vect = 0x%08x\n", ch, recv->state,
490 recv->recovery = 1;
496 /* Remember, len and recv->len are words. */
500 recv->state =
503 wakeup(&recv->event);
507 "vect = 0x%08x\n", ch, recv->state,
509 recv->recovery = 1;
522 SUME_MSI_RXDONE)) && recv->recovery) {
525 "%d\n", ch, vect, recv->state, loops);
532 recv->recovery = 0;
539 ifp = m->m_pkthdr.rcvif;
553 if (adapter->running == 0)
562 device_t dev = adapter->dev;
568 adapter->rid = PCIR_BAR(0);
569 adapter->bar0_addr = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
570 &adapter->rid, RF_ACTIVE);
571 if (adapter->bar0_addr == NULL) {
576 adapter->bt = rman_get_bustag(adapter->bar0_addr);
577 adapter->bh = rman_get_bushandle(adapter->bar0_addr);
578 adapter->bar0_len = rman_get_size(adapter->bar0_addr);
579 if (adapter->bar0_len != 1024) {
581 adapter->bar0_len);
593 adapter->irq.rid = 1; /* Should be 1, thus says pci_alloc_msi() */
594 adapter->irq.res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
595 &adapter->irq.rid, RF_SHAREABLE | RF_ACTIVE);
596 if (adapter->irq.res == NULL) {
602 error = bus_setup_intr(dev, adapter->irq.res, INTR_MPSAFE |
604 &adapter->irq.tag);
607 " %s: %d\n", adapter->irq.rid, "SUME_INTR", error);
629 adapter->num_sg = RIFFA_SG_ELEMS * ((reg >> 19) & 0xf);
630 adapter->sg_buf_size = RIFFA_SG_BUF_SIZE * ((reg >> 19) & 0xf);
688 struct nf_bb_desc *bouncebuf = (struct nf_bb_desc *) p->buf_addr;
690 bouncebuf->lower = (p->buf_hw_addr + sizeof(struct nf_bb_desc));
691 bouncebuf->upper = (p->buf_hw_addr + sizeof(struct nf_bb_desc)) >> 32;
692 bouncebuf->len = len >> 2;
699 struct riffa_chnl_dir *send = adapter->send[SUME_RIFFA_CHANNEL_REG];
705 RIFFA_RX_LEN_REG_OFF), send->len); /* words */
708 sume_fill_bb_desc(adapter, send, SUME_RIFFA_LEN(send->len));
711 send->state = SUME_RIFFA_CHAN_STATE_READY;
713 bus_dmamap_sync(send->ch_tag, send->ch_map,
718 SUME_RIFFA_LO_ADDR(send->buf_hw_addr));
721 SUME_RIFFA_HI_ADDR(send->buf_hw_addr));
723 RIFFA_RX_SG_LEN_REG_OFF), 4 * send->num_sg);
724 bus_dmamap_sync(send->ch_tag, send->ch_map,
740 struct sume_adapter *adapter = nf_priv->adapter;
741 struct riffa_chnl_dir *send = adapter->send[SUME_RIFFA_CHANNEL_REG];
754 if (send->state != SUME_RIFFA_CHAN_STATE_IDLE) {
759 data = (struct nf_regop_data *) (send->buf_addr +
761 data->addr = htole32(sifr->addr);
762 data->val = htole32(sifr->val);
764 data->rtag = htole32(++send->rtag);
765 data->optype = htole32(optype);
766 send->len = sizeof(struct nf_regop_data) / 4; /* words */
775 if (send->state != SUME_RIFFA_CHAN_STATE_LEN)
776 error = msleep(&send->event, &adapter->lock, 0,
781 send->state = SUME_RIFFA_CHAN_STATE_IDLE;
806 struct sume_adapter *adapter = nf_priv->adapter;
807 struct riffa_chnl_dir *recv = adapter->recv[SUME_RIFFA_CHANNEL_REG];
808 struct riffa_chnl_dir *send = adapter->send[SUME_RIFFA_CHANNEL_REG];
820 bus_dmamap_sync(recv->ch_tag, recv->ch_map,
826 if (recv->state != SUME_RIFFA_CHAN_STATE_READ)
827 error = msleep(&recv->event, &adapter->lock, 0,
830 if (recv->state != SUME_RIFFA_CHAN_STATE_READ || error == EWOULDBLOCK) {
832 device_printf(adapter->dev, "wait error: %d\n", error);
836 bus_dmamap_sync(recv->ch_tag, recv->ch_map,
844 data = (struct nf_regop_data *) (recv->buf_addr +
847 if (le32toh(data->rtag) != send->rtag)
848 device_printf(adapter->dev, "rtag error: 0x%08x 0x%08x\n",
849 le32toh(data->rtag), send->rtag);
851 sifr->val = le32toh(data->val);
852 recv->state = SUME_RIFFA_CHAN_STATE_IDLE;
855 send->state = SUME_RIFFA_CHAN_STATE_IDLE;
886 error = ifmedia_ioctl(ifp, ifr, &nf_priv->media, cmd);
932 struct ifmedia *ifm = &nf_priv->media;
934 if (IFM_TYPE(ifm->ifm_media) != IFM_ETHER)
937 if (IFM_SUBTYPE(ifm->ifm_media) == IFM_10G_SR)
940 if_setbaudrate(ifp, ifmedia_baudrate(ifm->ifm_media));
949 struct sume_adapter *adapter = nf_priv->adapter;
953 sifr.addr = SUME_STATUS_ADDR(nf_priv->port);
961 if (!link_status && nf_priv->link_up) {
963 nf_priv->link_up = 0;
964 if (adapter->sume_debug)
965 device_printf(adapter->dev, "port %d link state "
966 "changed to DOWN\n", nf_priv->unit);
967 } else if (link_status && !nf_priv->link_up) {
968 nf_priv->link_up = 1;
970 if (adapter->sume_debug)
971 device_printf(adapter->dev, "port %d link state "
972 "changed to UP\n", nf_priv->unit);
980 struct ifmedia *ifm = &nf_priv->media;
982 if (ifm->ifm_cur->ifm_media == (IFM_ETHER | IFM_10G_SR) &&
984 ifmr->ifm_active = IFM_ETHER | IFM_10G_SR;
986 ifmr->ifm_active = ifm->ifm_cur->ifm_media;
988 ifmr->ifm_status |= IFM_AVALID;
992 if (nf_priv->link_up)
993 ifmr->ifm_status |= IFM_ACTIVE;
997 * Packet to transmit. We take the packet data from the mbuf and copy it to the
999 * packet data are for metadata: sport/dport (depending on our source
1000 * interface), packet length and magic 0xcafe. We tell the SUME about the
1002 * the information about the start and length of the packet and trigger the
1010 struct sume_adapter *adapter = nf_priv->adapter;
1011 struct riffa_chnl_dir *send = adapter->send[SUME_RIFFA_CHANNEL_DATA];
1016 KASSERT(mtx_owned(&adapter->lock), ("SUME lock not owned"));
1017 KASSERT(send->state == SUME_RIFFA_CHAN_STATE_IDLE,
1025 if (m->m_pkthdr.len > SUME_MIN_PKT_SIZE)
1026 plen = m->m_pkthdr.len;
1028 if (adapter->sume_debug)
1029 device_printf(adapter->dev, "sending %d bytes to %s%d\n", plen,
1030 SUME_ETH_DEVICE_NAME, nf_priv->unit);
1032 outbuf = (uint8_t *) send->buf_addr + sizeof(struct nf_bb_desc);
1036 send->recovery = 0;
1039 if (m->m_pkthdr.len + sizeof(struct nf_metadata) >
1040 adapter->sg_buf_size) {
1041 device_printf(adapter->dev, "packet too big for bounce buffer "
1042 "(%d)\n", m->m_pkthdr.len);
1044 nf_priv->stats.tx_dropped++;
1048 bus_dmamap_sync(send->ch_tag, send->ch_map,
1052 if (m->m_pkthdr.len < SUME_MIN_PKT_SIZE)
1055 m_copydata(m, 0, m->m_pkthdr.len, outbuf + sizeof(struct nf_metadata));
1056 send->len = (sizeof(struct nf_metadata) + plen + 3) / 4;
1059 mdata->sport = htole16(1 << (nf_priv->port * 2 + 1));
1060 mdata->dport = htole16(1 << (nf_priv->port * 2));
1061 mdata->plen = htole16(plen);
1062 mdata->magic = htole16(SUME_RIFFA_MAGIC);
1063 mdata->t1 = htole32(0);
1064 mdata->t2 = htole32(0);
1070 RIFFA_RX_LEN_REG_OFF), send->len);
1073 sume_fill_bb_desc(adapter, send, SUME_RIFFA_LEN(send->len));
1076 send->state = SUME_RIFFA_CHAN_STATE_READY;
1081 SUME_RIFFA_LO_ADDR(send->buf_hw_addr));
1084 SUME_RIFFA_HI_ADDR(send->buf_hw_addr));
1086 RIFFA_RX_SG_LEN_REG_OFF), 4 * send->num_sg);
1088 bus_dmamap_sync(send->ch_tag, send->ch_map,
1091 nf_priv->stats.tx_packets++;
1092 nf_priv->stats.tx_bytes += plen;
1097 adapter->last_ifc = nf_priv->port;
1100 adapter->wd_counter = 0;
1109 struct sume_adapter *adapter = nf_priv->adapter;
1111 if (!adapter->running || !(if_getflags(ifp) & IFF_UP))
1115 if (adapter->send[SUME_RIFFA_CHANNEL_DATA]->state ==
1130 KASSERT(mtx_owned(&adapter->lock), ("SUME lock not owned"));
1132 last_ifc = adapter->last_ifc;
1136 if_t ifp = adapter->ifp[i % SUME_NPORTS];
1154 adapter->ifp[port] = ifp;
1157 nf_priv->adapter = adapter;
1158 nf_priv->unit = alloc_unr(unr);
1159 nf_priv->port = port;
1160 nf_priv->link_up = 0;
1162 if_initname(ifp, SUME_ETH_DEVICE_NAME, nf_priv->unit);
1170 hw_addr[ETHER_ADDR_LEN-1] = nf_priv->unit;
1173 ifmedia_init(&nf_priv->media, IFM_IMASK, sume_media_change,
1175 ifmedia_add(&nf_priv->media, IFM_ETHER | IFM_10G_SR, 0, NULL);
1176 ifmedia_set(&nf_priv->media, IFM_ETHER | IFM_10G_SR);
1199 device_t dev = adapter->dev;
1216 adapter->sg_buf_size,
1218 adapter->sg_buf_size,
1222 &rp[ch]->ch_tag);
1230 err = bus_dmamem_alloc(rp[ch]->ch_tag, (void **)
1231 &rp[ch]->buf_addr, BUS_DMA_WAITOK | BUS_DMA_COHERENT |
1232 BUS_DMA_ZERO, &rp[ch]->ch_map);
1239 bzero(rp[ch]->buf_addr, adapter->sg_buf_size);
1241 err = bus_dmamap_load(rp[ch]->ch_tag, rp[ch]->ch_map,
1242 rp[ch]->buf_addr, adapter->sg_buf_size, callback_dma,
1249 rp[ch]->buf_hw_addr = hw_addr;
1250 rp[ch]->num_sg = 1;
1251 rp[ch]->state = SUME_RIFFA_CHAN_STATE_IDLE;
1253 rp[ch]->rtag = SUME_INIT_RTAG;
1264 error = sume_probe_riffa_buffer(adapter, &adapter->recv, "recv");
1268 error = sume_probe_riffa_buffer(adapter, &adapter->send, "send");
1276 device_t dev = adapter->dev;
1285 0, "SUME top-level tree");
1291 &adapter->sume_debug, 0, "debug int leaf");
1295 CTLFLAG_RD, &adapter->packets_err, 0, "rx errors");
1297 CTLFLAG_RD, &adapter->bytes_err, 0, "rx error bytes");
1299 for (i = SUME_NPORTS - 1; i >= 0; i--) {
1300 if_t ifp = adapter->ifp[i];
1307 SUME_ETH_DEVICE_NAME, nf_priv->unit);
1318 &nf_priv->stats.ifc_down_bytes, 0, "ifc_down bytes");
1321 &nf_priv->stats.ifc_down_packets, 0, "ifc_down packets");
1325 "hw_rx_packets", CTLFLAG_RD, &nf_priv->stats.hw_rx_packets,
1330 "hw_tx_packets", CTLFLAG_RD, &nf_priv->stats.hw_tx_packets,
1335 "rx_bytes", CTLFLAG_RD, &nf_priv->stats.rx_bytes, 0,
1338 "rx_dropped", CTLFLAG_RD, &nf_priv->stats.rx_dropped, 0,
1341 "rx_packets", CTLFLAG_RD, &nf_priv->stats.rx_packets, 0,
1346 "tx_bytes", CTLFLAG_RD, &nf_priv->stats.tx_bytes, 0,
1349 "tx_dropped", CTLFLAG_RD, &nf_priv->stats.tx_dropped, 0,
1352 "tx_packets", CTLFLAG_RD, &nf_priv->stats.tx_packets, 0,
1362 if (!adapter->running)
1365 taskqueue_enqueue(adapter->tq, &adapter->stat_task);
1368 if (adapter->send[SUME_RIFFA_CHANNEL_DATA]->state !=
1369 SUME_RIFFA_CHAN_STATE_IDLE && ++adapter->wd_counter >= 3) {
1371 device_printf(adapter->dev, "TX stuck, resetting adapter.\n");
1374 adapter->send[SUME_RIFFA_CHANNEL_DATA]->state =
1376 adapter->wd_counter = 0;
1382 callout_reset(&adapter->timer, 1 * hz, sume_local_timer, adapter);
1392 if_t ifp = adapter->ifp[i];
1401 sifr.addr = SUME_STAT_RX_ADDR(nf_priv->port);
1405 nf_priv->stats.hw_rx_packets += sifr.val;
1408 sifr.addr = SUME_STAT_TX_ADDR(nf_priv->port);
1412 nf_priv->stats.hw_tx_packets += sifr.val;
1421 adapter->dev = dev;
1424 mtx_init(&adapter->lock, "Global lock", NULL, MTX_DEF);
1426 adapter->running = 0;
1448 adapter->running = 1;
1450 callout_init(&adapter->timer, 1);
1451 TASK_INIT(&adapter->stat_task, 0, sume_get_stats, adapter);
1453 adapter->tq = taskqueue_create("sume_stats", M_NOWAIT,
1454 taskqueue_thread_enqueue, &adapter->tq);
1455 taskqueue_start_threads(&adapter->tq, 1, PI_NET, "%s stattaskq",
1456 device_get_nameunit(adapter->dev));
1458 callout_reset(&adapter->timer, 1 * hz, sume_local_timer, adapter);
1478 if (pp[ch]->buf_hw_addr != 0) {
1479 bus_dmamem_free(pp[ch]->ch_tag, pp[ch]->buf_addr,
1480 pp[ch]->ch_map);
1481 pp[ch]->buf_hw_addr = 0;
1491 if (adapter->send != NULL) {
1492 sume_remove_riffa_buffer(adapter, adapter->send);
1493 free(adapter->send, M_SUME);
1494 adapter->send = NULL;
1496 if (adapter->recv != NULL) {
1497 sume_remove_riffa_buffer(adapter, adapter->recv);
1498 free(adapter->recv, M_SUME);
1499 adapter->recv = NULL;
1510 KASSERT(mtx_initialized(&adapter->lock), ("SUME mutex not "
1512 adapter->running = 0;
1515 callout_drain(&adapter->timer);
1517 if (adapter->tq) {
1518 taskqueue_drain(adapter->tq, &adapter->stat_task);
1519 taskqueue_free(adapter->tq);
1523 if_t ifp = adapter->ifp[i];
1532 ifmedia_removeall(&nf_priv->media);
1533 free_unr(unr, nf_priv->unit);
1544 if (adapter->irq.tag)
1545 bus_teardown_intr(dev, adapter->irq.res, adapter->irq.tag);
1546 if (adapter->irq.res)
1547 bus_release_resource(dev, SYS_RES_IRQ, adapter->irq.rid,
1548 adapter->irq.res);
1552 if (adapter->bar0_addr)
1553 bus_release_resource(dev, SYS_RES_MEMORY, adapter->rid,
1554 adapter->bar0_addr);
1556 mtx_destroy(&adapter->lock);