1/* 2 * Intel MIC Platform Software Stack (MPSS) 3 * 4 * Copyright(c) 2013 Intel Corporation. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License, version 2, as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, but 11 * WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 * General Public License for more details. 14 * 15 * The full GNU General Public License is included in this distribution in 16 * the file called "COPYING". 17 * 18 * Intel MIC Host driver. 19 * 20 */ 21#ifndef MIC_VIRTIO_H 22#define MIC_VIRTIO_H 23 24#include <linux/virtio_config.h> 25#include <linux/mic_ioctl.h> 26 27/* 28 * Note on endianness. 29 * 1. Host can be both BE or LE 30 * 2. Guest/card is LE. Host uses le_to_cpu to access desc/avail 31 * rings and ioreadXX/iowriteXX to access used ring. 32 * 3. Device page exposed by host to guest contains LE values. Guest 33 * accesses these using ioreadXX/iowriteXX etc. This way in general we 34 * obey the virtio spec according to which guest works with native 35 * endianness and host is aware of guest endianness and does all 36 * required endianness conversion. 37 * 4. Data provided from user space to guest (in ADD_DEVICE and 38 * CONFIG_CHANGE ioctl's) is not interpreted by the driver and should be 39 * in guest endianness. 40 */ 41 42/** 43 * struct mic_vringh - Virtio ring host information. 44 * 45 * @vring: The MIC vring used for setting up user space mappings. 46 * @vrh: The host VRINGH used for accessing the card vrings. 47 * @riov: The VRINGH read kernel IOV. 48 * @wiov: The VRINGH write kernel IOV. 49 * @vr_mutex: Mutex for synchronizing access to the VRING. 50 * @buf: Temporary kernel buffer used to copy in/out data 51 * from/to the card via DMA. 52 * @buf_da: dma address of buf. 53 * @mvdev: Back pointer to MIC virtio device for vringh_notify(..). 54 * @head: The VRINGH head index address passed to vringh_getdesc_kern(..). 55 */ 56struct mic_vringh { 57 struct mic_vring vring; 58 struct vringh vrh; 59 struct vringh_kiov riov; 60 struct vringh_kiov wiov; 61 struct mutex vr_mutex; 62 void *buf; 63 dma_addr_t buf_da; 64 struct mic_vdev *mvdev; 65 u16 head; 66}; 67 68/** 69 * struct mic_vdev - Host information for a card Virtio device. 70 * 71 * @virtio_id - Virtio device id. 72 * @waitq - Waitqueue to allow ring3 apps to poll. 73 * @mdev - Back pointer to host MIC device. 74 * @poll_wake - Used for waking up threads blocked in poll. 75 * @out_bytes - Debug stats for number of bytes copied from host to card. 76 * @in_bytes - Debug stats for number of bytes copied from card to host. 77 * @out_bytes_dma - Debug stats for number of bytes copied from host to card 78 * using DMA. 79 * @in_bytes_dma - Debug stats for number of bytes copied from card to host 80 * using DMA. 81 * @tx_len_unaligned - Debug stats for number of bytes copied to the card where 82 * the transfer length did not have the required DMA alignment. 83 * @tx_dst_unaligned - Debug stats for number of bytes copied where the 84 * destination address on the card did not have the required DMA alignment. 85 * @mvr - Store per VRING data structures. 86 * @virtio_bh_work - Work struct used to schedule virtio bottom half handling. 87 * @dd - Virtio device descriptor. 88 * @dc - Virtio device control fields. 89 * @list - List of Virtio devices. 90 * @virtio_db - The doorbell used by the card to interrupt the host. 91 * @virtio_cookie - The cookie returned while requesting interrupts. 92 */ 93struct mic_vdev { 94 int virtio_id; 95 wait_queue_head_t waitq; 96 struct mic_device *mdev; 97 int poll_wake; 98 unsigned long out_bytes; 99 unsigned long in_bytes; 100 unsigned long out_bytes_dma; 101 unsigned long in_bytes_dma; 102 unsigned long tx_len_unaligned; 103 unsigned long tx_dst_unaligned; 104 struct mic_vringh mvr[MIC_MAX_VRINGS]; 105 struct work_struct virtio_bh_work; 106 struct mic_device_desc *dd; 107 struct mic_device_ctrl *dc; 108 struct list_head list; 109 int virtio_db; 110 struct mic_irq *virtio_cookie; 111}; 112 113void mic_virtio_uninit(struct mic_device *mdev); 114int mic_virtio_add_device(struct mic_vdev *mvdev, 115 void __user *argp); 116void mic_virtio_del_device(struct mic_vdev *mvdev); 117int mic_virtio_config_change(struct mic_vdev *mvdev, 118 void __user *argp); 119int mic_virtio_copy_desc(struct mic_vdev *mvdev, 120 struct mic_copy_desc *request); 121void mic_virtio_reset_devices(struct mic_device *mdev); 122void mic_bh_handler(struct work_struct *work); 123 124/* Helper API to obtain the MIC PCIe device */ 125static inline struct device *mic_dev(struct mic_vdev *mvdev) 126{ 127 return mvdev->mdev->sdev->parent; 128} 129 130/* Helper API to check if a virtio device is initialized */ 131static inline int mic_vdev_inited(struct mic_vdev *mvdev) 132{ 133 /* Device has not been created yet */ 134 if (!mvdev->dd || !mvdev->dd->type) { 135 dev_err(mic_dev(mvdev), "%s %d err %d\n", 136 __func__, __LINE__, -EINVAL); 137 return -EINVAL; 138 } 139 140 /* Device has been removed/deleted */ 141 if (mvdev->dd->type == -1) { 142 dev_err(mic_dev(mvdev), "%s %d err %d\n", 143 __func__, __LINE__, -ENODEV); 144 return -ENODEV; 145 } 146 147 return 0; 148} 149 150/* Helper API to check if a virtio device is running */ 151static inline bool mic_vdevup(struct mic_vdev *mvdev) 152{ 153 return !!mvdev->dd->status; 154} 155#endif 156