Lines Matching full:fifo

38 /* Virtual devices sharing the TM FIFO. */
76 * @fifo: pointer to the tmfifo structure
95 struct mlxbf_tmfifo *fifo; member
134 * @tx_buf: tx buffer used to buffer data before writing into the FIFO
150 * @fifo: pointer to the tmfifo structure
155 struct mlxbf_tmfifo *fifo; member
180 * @rx_fifo_size: number of entries of the Rx FIFO
181 * @tx_fifo_size: number of entries of the Tx FIFO
211 * @len: payload length in network byte order. Messages sent into the FIFO
245 /* Free vrings of the FIFO device. */
246 static void mlxbf_tmfifo_free_vrings(struct mlxbf_tmfifo *fifo, in mlxbf_tmfifo_free_vrings() argument
267 /* Allocate vrings for the FIFO. */
268 static int mlxbf_tmfifo_alloc_vrings(struct mlxbf_tmfifo *fifo, in mlxbf_tmfifo_alloc_vrings() argument
279 vring->fifo = fifo; in mlxbf_tmfifo_alloc_vrings()
290 mlxbf_tmfifo_free_vrings(fifo, tm_vdev); in mlxbf_tmfifo_alloc_vrings()
302 /* Disable interrupts of the FIFO device. */
303 static void mlxbf_tmfifo_disable_irqs(struct mlxbf_tmfifo *fifo) in mlxbf_tmfifo_disable_irqs() argument
308 irq = fifo->irq_info[i].irq; in mlxbf_tmfifo_disable_irqs()
309 fifo->irq_info[i].irq = 0; in mlxbf_tmfifo_disable_irqs()
319 if (!test_and_set_bit(irq_info->index, &irq_info->fifo->pend_events)) in mlxbf_tmfifo_irq_handler()
320 schedule_work(&irq_info->fifo->work); in mlxbf_tmfifo_irq_handler()
440 struct mlxbf_tmfifo *fifo = container_of(t, struct mlxbf_tmfifo, timer); in mlxbf_tmfifo_timer() local
443 rx = !test_and_set_bit(MLXBF_TM_RX_HWM_IRQ, &fifo->pend_events); in mlxbf_tmfifo_timer()
444 tx = !test_and_set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events); in mlxbf_tmfifo_timer()
447 schedule_work(&fifo->work); in mlxbf_tmfifo_timer()
449 mod_timer(&fifo->timer, jiffies + MLXBF_TMFIFO_TIMER_INTERVAL); in mlxbf_tmfifo_timer()
509 /* Get the number of available words in Rx FIFO for receiving. */
510 static int mlxbf_tmfifo_get_rx_avail(struct mlxbf_tmfifo *fifo) in mlxbf_tmfifo_get_rx_avail() argument
514 sts = readq(fifo->rx.sts); in mlxbf_tmfifo_get_rx_avail()
519 static int mlxbf_tmfifo_get_tx_avail(struct mlxbf_tmfifo *fifo, int vdev_id) in mlxbf_tmfifo_get_tx_avail() argument
525 /* Reserve some room in FIFO for console messages. */ in mlxbf_tmfifo_get_tx_avail()
527 tx_reserve = fifo->tx_fifo_size / MLXBF_TMFIFO_RESERVE_RATIO; in mlxbf_tmfifo_get_tx_avail()
531 sts = readq(fifo->tx.sts); in mlxbf_tmfifo_get_tx_avail()
533 return fifo->tx_fifo_size - tx_reserve - count; in mlxbf_tmfifo_get_tx_avail()
537 static void mlxbf_tmfifo_console_tx(struct mlxbf_tmfifo *fifo, int avail) in mlxbf_tmfifo_console_tx() argument
550 cons = fifo->vdev[VIRTIO_ID_CONSOLE]; in mlxbf_tmfifo_console_tx()
567 writeq(*(u64 *)&hdr, fifo->tx.data); in mlxbf_tmfifo_console_tx()
570 spin_lock_irqsave(&fifo->spin_lock[0], flags); in mlxbf_tmfifo_console_tx()
584 writeq(data, fifo->tx.data); in mlxbf_tmfifo_console_tx()
597 spin_unlock_irqrestore(&fifo->spin_lock[0], flags); in mlxbf_tmfifo_console_tx()
606 struct mlxbf_tmfifo *fifo = vring->fifo; in mlxbf_tmfifo_rxtx_word() local
613 /* Read a word from FIFO for Rx. */ in mlxbf_tmfifo_rxtx_word()
615 data = readq(fifo->rx.data); in mlxbf_tmfifo_rxtx_word()
642 /* Write the word into FIFO for Tx. */ in mlxbf_tmfifo_rxtx_word()
644 writeq(data, fifo->tx.data); in mlxbf_tmfifo_rxtx_word()
658 struct mlxbf_tmfifo *fifo = vring->fifo; in mlxbf_tmfifo_rxtx_header() local
666 /* Drain one word from the FIFO. */ in mlxbf_tmfifo_rxtx_header()
667 *(u64 *)&hdr = readq(fifo->rx.data); in mlxbf_tmfifo_rxtx_header()
677 config = &fifo->vdev[vdev_id]->config.net; in mlxbf_tmfifo_rxtx_header()
694 struct mlxbf_tmfifo_vdev *tm_dev2 = fifo->vdev[vdev_id]; in mlxbf_tmfifo_rxtx_header()
720 writeq(*(u64 *)&hdr, fifo->tx.data); in mlxbf_tmfifo_rxtx_header()
725 fifo->vring[is_rx] = vring; in mlxbf_tmfifo_rxtx_header()
737 struct mlxbf_tmfifo *fifo = vring->fifo; in mlxbf_tmfifo_rxtx_one_desc() local
744 vdev = &fifo->vdev[vring->vdev_id]->vdev; in mlxbf_tmfifo_rxtx_one_desc()
800 fifo->vring[is_rx] = NULL; in mlxbf_tmfifo_rxtx_one_desc()
817 spin_lock_irqsave(&fifo->spin_lock[is_rx], flags); in mlxbf_tmfifo_rxtx_one_desc()
819 spin_unlock_irqrestore(&fifo->spin_lock[is_rx], flags); in mlxbf_tmfifo_rxtx_one_desc()
859 vring->fifo->vring[0] = NULL; in mlxbf_tmfifo_check_tx_timeout()
868 spin_lock_irqsave(&vring->fifo->spin_lock[0], flags); in mlxbf_tmfifo_check_tx_timeout()
870 spin_unlock_irqrestore(&vring->fifo->spin_lock[0], flags); in mlxbf_tmfifo_check_tx_timeout()
877 struct mlxbf_tmfifo *fifo; in mlxbf_tmfifo_rxtx() local
880 fifo = vring->fifo; in mlxbf_tmfifo_rxtx()
883 if (!fifo || !fifo->vdev[devid]) in mlxbf_tmfifo_rxtx()
887 if (fifo->vring[is_rx] && fifo->vring[is_rx] != vring) in mlxbf_tmfifo_rxtx()
896 /* Get available FIFO space. */ in mlxbf_tmfifo_rxtx()
899 avail = mlxbf_tmfifo_get_rx_avail(fifo); in mlxbf_tmfifo_rxtx()
901 avail = mlxbf_tmfifo_get_tx_avail(fifo, devid); in mlxbf_tmfifo_rxtx()
910 writeq(0, vring->fifo->tx.data); in mlxbf_tmfifo_rxtx()
919 mlxbf_tmfifo_console_tx(fifo, avail); in mlxbf_tmfifo_rxtx()
933 static void mlxbf_tmfifo_work_rxtx(struct mlxbf_tmfifo *fifo, int queue_id, in mlxbf_tmfifo_work_rxtx() argument
940 if (!test_and_clear_bit(irq_id, &fifo->pend_events) || in mlxbf_tmfifo_work_rxtx()
941 !fifo->irq_info[irq_id].irq) in mlxbf_tmfifo_work_rxtx()
945 tm_vdev = fifo->vdev[i]; in mlxbf_tmfifo_work_rxtx()
957 struct mlxbf_tmfifo *fifo; in mlxbf_tmfifo_work_handler() local
959 fifo = container_of(work, struct mlxbf_tmfifo, work); in mlxbf_tmfifo_work_handler()
960 if (!fifo->is_ready) in mlxbf_tmfifo_work_handler()
963 mutex_lock(&fifo->lock); in mlxbf_tmfifo_work_handler()
966 mlxbf_tmfifo_work_rxtx(fifo, MLXBF_TMFIFO_VRING_TX, in mlxbf_tmfifo_work_handler()
970 mlxbf_tmfifo_work_rxtx(fifo, MLXBF_TMFIFO_VRING_RX, in mlxbf_tmfifo_work_handler()
973 mutex_unlock(&fifo->lock); in mlxbf_tmfifo_work_handler()
981 struct mlxbf_tmfifo *fifo; in mlxbf_tmfifo_virtio_notify() local
984 fifo = vring->fifo; in mlxbf_tmfifo_virtio_notify()
998 spin_lock_irqsave(&fifo->spin_lock[0], flags); in mlxbf_tmfifo_virtio_notify()
999 tm_vdev = fifo->vdev[VIRTIO_ID_CONSOLE]; in mlxbf_tmfifo_virtio_notify()
1001 spin_unlock_irqrestore(&fifo->spin_lock[0], flags); in mlxbf_tmfifo_virtio_notify()
1002 set_bit(MLXBF_TM_TX_LWM_IRQ, &fifo->pend_events); in mlxbf_tmfifo_virtio_notify()
1004 &fifo->pend_events)) { in mlxbf_tmfifo_virtio_notify()
1008 if (test_and_set_bit(MLXBF_TM_RX_HWM_IRQ, &fifo->pend_events)) in mlxbf_tmfifo_virtio_notify()
1012 schedule_work(&fifo->work); in mlxbf_tmfifo_virtio_notify()
1187 /* Create vdev for the FIFO. */
1189 struct mlxbf_tmfifo *fifo, in mlxbf_tmfifo_create_vdev() argument
1196 mutex_lock(&fifo->lock); in mlxbf_tmfifo_create_vdev()
1198 tm_vdev = fifo->vdev[vdev_id]; in mlxbf_tmfifo_create_vdev()
1219 if (mlxbf_tmfifo_alloc_vrings(fifo, tm_vdev)) { in mlxbf_tmfifo_create_vdev()
1230 fifo->vdev[vdev_id] = tm_vdev; in mlxbf_tmfifo_create_vdev()
1240 mutex_unlock(&fifo->lock); in mlxbf_tmfifo_create_vdev()
1244 mlxbf_tmfifo_free_vrings(fifo, tm_vdev); in mlxbf_tmfifo_create_vdev()
1245 fifo->vdev[vdev_id] = NULL; in mlxbf_tmfifo_create_vdev()
1251 mutex_unlock(&fifo->lock); in mlxbf_tmfifo_create_vdev()
1255 /* Delete vdev for the FIFO. */
1256 static int mlxbf_tmfifo_delete_vdev(struct mlxbf_tmfifo *fifo, int vdev_id) in mlxbf_tmfifo_delete_vdev() argument
1260 mutex_lock(&fifo->lock); in mlxbf_tmfifo_delete_vdev()
1263 tm_vdev = fifo->vdev[vdev_id]; in mlxbf_tmfifo_delete_vdev()
1266 mlxbf_tmfifo_free_vrings(fifo, tm_vdev); in mlxbf_tmfifo_delete_vdev()
1267 fifo->vdev[vdev_id] = NULL; in mlxbf_tmfifo_delete_vdev()
1270 mutex_unlock(&fifo->lock); in mlxbf_tmfifo_delete_vdev()
1291 static void mlxbf_tmfifo_set_threshold(struct mlxbf_tmfifo *fifo) in mlxbf_tmfifo_set_threshold() argument
1295 /* Get Tx FIFO size and set the low/high watermark. */ in mlxbf_tmfifo_set_threshold()
1296 ctl = readq(fifo->tx.ctl); in mlxbf_tmfifo_set_threshold()
1297 fifo->tx_fifo_size = in mlxbf_tmfifo_set_threshold()
1301 fifo->tx_fifo_size / 2); in mlxbf_tmfifo_set_threshold()
1304 fifo->tx_fifo_size - 1); in mlxbf_tmfifo_set_threshold()
1305 writeq(ctl, fifo->tx.ctl); in mlxbf_tmfifo_set_threshold()
1307 /* Get Rx FIFO size and set the low/high watermark. */ in mlxbf_tmfifo_set_threshold()
1308 ctl = readq(fifo->rx.ctl); in mlxbf_tmfifo_set_threshold()
1309 fifo->rx_fifo_size = in mlxbf_tmfifo_set_threshold()
1315 writeq(ctl, fifo->rx.ctl); in mlxbf_tmfifo_set_threshold()
1318 static void mlxbf_tmfifo_cleanup(struct mlxbf_tmfifo *fifo) in mlxbf_tmfifo_cleanup() argument
1322 fifo->is_ready = false; in mlxbf_tmfifo_cleanup()
1323 del_timer_sync(&fifo->timer); in mlxbf_tmfifo_cleanup()
1324 mlxbf_tmfifo_disable_irqs(fifo); in mlxbf_tmfifo_cleanup()
1325 cancel_work_sync(&fifo->work); in mlxbf_tmfifo_cleanup()
1327 mlxbf_tmfifo_delete_vdev(fifo, i); in mlxbf_tmfifo_cleanup()
1335 struct mlxbf_tmfifo *fifo; in mlxbf_tmfifo_probe() local
1345 fifo = devm_kzalloc(dev, sizeof(*fifo), GFP_KERNEL); in mlxbf_tmfifo_probe()
1346 if (!fifo) in mlxbf_tmfifo_probe()
1349 spin_lock_init(&fifo->spin_lock[0]); in mlxbf_tmfifo_probe()
1350 spin_lock_init(&fifo->spin_lock[1]); in mlxbf_tmfifo_probe()
1351 INIT_WORK(&fifo->work, mlxbf_tmfifo_work_handler); in mlxbf_tmfifo_probe()
1352 mutex_init(&fifo->lock); in mlxbf_tmfifo_probe()
1354 /* Get the resource of the Rx FIFO. */ in mlxbf_tmfifo_probe()
1355 fifo->res0 = devm_platform_ioremap_resource(pdev, 0); in mlxbf_tmfifo_probe()
1356 if (IS_ERR(fifo->res0)) in mlxbf_tmfifo_probe()
1357 return PTR_ERR(fifo->res0); in mlxbf_tmfifo_probe()
1359 /* Get the resource of the Tx FIFO. */ in mlxbf_tmfifo_probe()
1360 fifo->res1 = devm_platform_ioremap_resource(pdev, 1); in mlxbf_tmfifo_probe()
1361 if (IS_ERR(fifo->res1)) in mlxbf_tmfifo_probe()
1362 return PTR_ERR(fifo->res1); in mlxbf_tmfifo_probe()
1365 fifo->rx.ctl = fifo->res1 + MLXBF_TMFIFO_RX_CTL_BF3; in mlxbf_tmfifo_probe()
1366 fifo->rx.sts = fifo->res1 + MLXBF_TMFIFO_RX_STS_BF3; in mlxbf_tmfifo_probe()
1367 fifo->rx.data = fifo->res0 + MLXBF_TMFIFO_RX_DATA_BF3; in mlxbf_tmfifo_probe()
1368 fifo->tx.ctl = fifo->res1 + MLXBF_TMFIFO_TX_CTL_BF3; in mlxbf_tmfifo_probe()
1369 fifo->tx.sts = fifo->res1 + MLXBF_TMFIFO_TX_STS_BF3; in mlxbf_tmfifo_probe()
1370 fifo->tx.data = fifo->res0 + MLXBF_TMFIFO_TX_DATA_BF3; in mlxbf_tmfifo_probe()
1372 fifo->rx.ctl = fifo->res0 + MLXBF_TMFIFO_RX_CTL; in mlxbf_tmfifo_probe()
1373 fifo->rx.sts = fifo->res0 + MLXBF_TMFIFO_RX_STS; in mlxbf_tmfifo_probe()
1374 fifo->rx.data = fifo->res0 + MLXBF_TMFIFO_RX_DATA; in mlxbf_tmfifo_probe()
1375 fifo->tx.ctl = fifo->res1 + MLXBF_TMFIFO_TX_CTL; in mlxbf_tmfifo_probe()
1376 fifo->tx.sts = fifo->res1 + MLXBF_TMFIFO_TX_STS; in mlxbf_tmfifo_probe()
1377 fifo->tx.data = fifo->res1 + MLXBF_TMFIFO_TX_DATA; in mlxbf_tmfifo_probe()
1380 platform_set_drvdata(pdev, fifo); in mlxbf_tmfifo_probe()
1382 timer_setup(&fifo->timer, mlxbf_tmfifo_timer, 0); in mlxbf_tmfifo_probe()
1385 fifo->irq_info[i].index = i; in mlxbf_tmfifo_probe()
1386 fifo->irq_info[i].fifo = fifo; in mlxbf_tmfifo_probe()
1387 fifo->irq_info[i].irq = platform_get_irq(pdev, i); in mlxbf_tmfifo_probe()
1388 rc = devm_request_irq(dev, fifo->irq_info[i].irq, in mlxbf_tmfifo_probe()
1390 "tmfifo", &fifo->irq_info[i]); in mlxbf_tmfifo_probe()
1393 fifo->irq_info[i].irq = 0; in mlxbf_tmfifo_probe()
1398 mlxbf_tmfifo_set_threshold(fifo); in mlxbf_tmfifo_probe()
1401 rc = mlxbf_tmfifo_create_vdev(dev, fifo, VIRTIO_ID_CONSOLE, 0, NULL, 0); in mlxbf_tmfifo_probe()
1414 rc = mlxbf_tmfifo_create_vdev(dev, fifo, VIRTIO_ID_NET, in mlxbf_tmfifo_probe()
1420 mod_timer(&fifo->timer, jiffies + MLXBF_TMFIFO_TIMER_INTERVAL); in mlxbf_tmfifo_probe()
1425 fifo->is_ready = true; in mlxbf_tmfifo_probe()
1429 mlxbf_tmfifo_cleanup(fifo); in mlxbf_tmfifo_probe()
1436 struct mlxbf_tmfifo *fifo = platform_get_drvdata(pdev); in mlxbf_tmfifo_remove() local
1438 mlxbf_tmfifo_cleanup(fifo); in mlxbf_tmfifo_remove()