Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /* virtio-net.c - etherboot driver for virtio network interface
  2. *
  3. * (c) Copyright 2008 Bull S.A.S.
  4. *
  5. * Author: Laurent Vivier <Laurent.Vivier@bull.net>
  6. *
  7. * some parts from Linux Virtio PCI driver
  8. *
  9. * Copyright IBM Corp. 2007
  10. * Authors: Anthony Liguori <aliguori@us.ibm.com>
  11. *
  12. * some parts from Linux Virtio Ring
  13. *
  14. * Copyright Rusty Russell IBM Corporation 2007
  15. *
  16. * This work is licensed under the terms of the GNU GPL, version 2 or later.
  17. * See the COPYING file in the top-level directory.
  18. *
  19. *
  20. */
  21. #include "etherboot.h"
  22. #include "nic.h"
  23. #include "gpxe/virtio-ring.h"
  24. #include "gpxe/virtio-pci.h"
  25. #include "virtio-net.h"
  26. #define BUG() do { \
  27. printf("BUG: failure at %s:%d/%s()!\n", \
  28. __FILE__, __LINE__, __FUNCTION__); \
  29. while(1); \
  30. } while (0)
  31. #define BUG_ON(condition) do { if (condition) BUG(); } while (0)
  32. /* Ethernet header */
  33. struct eth_hdr {
  34. unsigned char dst_addr[ETH_ALEN];
  35. unsigned char src_addr[ETH_ALEN];
  36. unsigned short type;
  37. };
  38. struct eth_frame {
  39. struct eth_hdr hdr;
  40. unsigned char data[ETH_FRAME_LEN];
  41. };
  42. typedef unsigned char virtio_queue_t[PAGE_MASK + vring_size(MAX_QUEUE_NUM)];
  43. /* TX: virtio header and eth buffer */
  44. static struct virtio_net_hdr tx_virtio_hdr;
  45. static struct eth_frame tx_eth_frame;
  46. /* RX: virtio headers and buffers */
  47. #define RX_BUF_NB 6
  48. static struct virtio_net_hdr rx_hdr[RX_BUF_NB];
  49. static unsigned char rx_buffer[RX_BUF_NB][ETH_FRAME_LEN];
  50. /* virtio queues and vrings */
  51. enum {
  52. RX_INDEX = 0,
  53. TX_INDEX,
  54. QUEUE_NB
  55. };
  56. static virtio_queue_t queue[QUEUE_NB];
  57. static struct vring vring[QUEUE_NB];
  58. static u16 free_head[QUEUE_NB];
  59. static u16 last_used_idx[QUEUE_NB];
  60. static u16 vdata[QUEUE_NB][MAX_QUEUE_NUM];
  61. /*
  62. * Virtio PCI interface
  63. *
  64. */
  65. static int vp_find_vq(struct nic *nic, int queue_index)
  66. {
  67. struct vring * vr = &vring[queue_index];
  68. u16 num;
  69. /* select the queue */
  70. outw(queue_index, nic->ioaddr + VIRTIO_PCI_QUEUE_SEL);
  71. /* check if the queue is available */
  72. num = inw(nic->ioaddr + VIRTIO_PCI_QUEUE_NUM);
  73. if (!num) {
  74. printf("ERROR: queue size is 0\n");
  75. return -1;
  76. }
  77. if (num > MAX_QUEUE_NUM) {
  78. printf("ERROR: queue size %d > %d\n", num, MAX_QUEUE_NUM);
  79. return -1;
  80. }
  81. /* check if the queue is already active */
  82. if (inl(nic->ioaddr + VIRTIO_PCI_QUEUE_PFN)) {
  83. printf("ERROR: queue already active\n");
  84. return -1;
  85. }
  86. /* initialize the queue */
  87. vring_init(vr, num, (unsigned char*)&queue[queue_index]);
  88. /* activate the queue
  89. *
  90. * NOTE: vr->desc is initialized by vring_init()
  91. */
  92. outl((unsigned long)virt_to_phys(vr->desc) >> PAGE_SHIFT,
  93. nic->ioaddr + VIRTIO_PCI_QUEUE_PFN);
  94. return num;
  95. }
  96. /*
  97. * Virtual ring management
  98. *
  99. */
  100. static void vring_enable_cb(int queue_index)
  101. {
  102. vring[queue_index].avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
  103. }
  104. static void vring_disable_cb(int queue_index)
  105. {
  106. vring[queue_index].avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
  107. }
  108. /*
  109. * vring_free
  110. *
  111. * put at the begin of the free list the current desc[head]
  112. */
  113. static void vring_detach(int queue_index, unsigned int head)
  114. {
  115. struct vring *vr = &vring[queue_index];
  116. unsigned int i;
  117. /* find end of given descriptor */
  118. i = head;
  119. while (vr->desc[i].flags & VRING_DESC_F_NEXT)
  120. i = vr->desc[i].next;
  121. /* link it with free list and point to it */
  122. vr->desc[i].next = free_head[queue_index];
  123. wmb();
  124. free_head[queue_index] = head;
  125. }
  126. /*
  127. * vring_more_used
  128. *
  129. * is there some used buffers ?
  130. *
  131. */
  132. static inline int vring_more_used(int queue_index)
  133. {
  134. wmb();
  135. return last_used_idx[queue_index] != vring[queue_index].used->idx;
  136. }
  137. /*
  138. * vring_get_buf
  139. *
  140. * get a buffer from the used list
  141. *
  142. */
  143. static int vring_get_buf(int queue_index, unsigned int *len)
  144. {
  145. struct vring *vr = &vring[queue_index];
  146. struct vring_used_elem *elem;
  147. u32 id;
  148. int ret;
  149. BUG_ON(!vring_more_used(queue_index));
  150. elem = &vr->used->ring[last_used_idx[queue_index] % vr->num];
  151. wmb();
  152. id = elem->id;
  153. if (len != NULL)
  154. *len = elem->len;
  155. ret = vdata[queue_index][id];
  156. vring_detach(queue_index, id);
  157. last_used_idx[queue_index]++;
  158. return ret;
  159. }
  160. static void vring_add_buf(int queue_index,
  161. struct vring_list list[],
  162. unsigned int out, unsigned int in,
  163. int index, int num_added)
  164. {
  165. struct vring *vr = &vring[queue_index];
  166. int i, avail, head, prev;
  167. BUG_ON(queue_index >= QUEUE_NB);
  168. BUG_ON(out + in == 0);
  169. prev = 0;
  170. head = free_head[queue_index];
  171. for (i = head; out; i = vr->desc[i].next, out--) {
  172. vr->desc[i].flags = VRING_DESC_F_NEXT;
  173. vr->desc[i].addr = (u64)virt_to_phys(list->addr);
  174. vr->desc[i].len = list->length;
  175. prev = i;
  176. list++;
  177. }
  178. for ( ; in; i = vr->desc[i].next, in--) {
  179. vr->desc[i].flags = VRING_DESC_F_NEXT|VRING_DESC_F_WRITE;
  180. vr->desc[i].addr = (u64)virt_to_phys(list->addr);
  181. vr->desc[i].len = list->length;
  182. prev = i;
  183. list++;
  184. }
  185. vr->desc[prev].flags &= ~VRING_DESC_F_NEXT;
  186. free_head[queue_index] = i;
  187. vdata[queue_index][head] = index;
  188. avail = (vr->avail->idx + num_added) % vr->num;
  189. vr->avail->ring[avail] = head;
  190. wmb();
  191. }
  192. static void vring_kick(struct nic *nic, int queue_index, int num_added)
  193. {
  194. struct vring *vr = &vring[queue_index];
  195. wmb();
  196. vr->avail->idx += num_added;
  197. mb();
  198. if (!(vr->used->flags & VRING_USED_F_NO_NOTIFY))
  199. vp_notify(nic, queue_index);
  200. }
  201. /*
  202. * virtnet_disable
  203. *
  204. * Turn off ethernet interface
  205. *
  206. */
  207. static void virtnet_disable(struct nic *nic)
  208. {
  209. int i;
  210. for (i = 0; i < QUEUE_NB; i++) {
  211. vring_disable_cb(i);
  212. vp_del_vq(nic, i);
  213. }
  214. vp_reset(nic);
  215. }
  216. /*
  217. * virtnet_poll
  218. *
  219. * Wait for a frame
  220. *
  221. * return true if there is a packet ready to read
  222. *
  223. * nic->packet should contain data on return
  224. * nic->packetlen should contain length of data
  225. *
  226. */
  227. static int virtnet_poll(struct nic *nic, int retrieve)
  228. {
  229. unsigned int len;
  230. u16 token;
  231. struct virtio_net_hdr *hdr;
  232. struct vring_list list[2];
  233. if (!vring_more_used(RX_INDEX))
  234. return 0;
  235. if (!retrieve)
  236. return 1;
  237. token = vring_get_buf(RX_INDEX, &len);
  238. BUG_ON(len > sizeof(struct virtio_net_hdr) + ETH_FRAME_LEN);
  239. hdr = &rx_hdr[token]; /* FIXME: check flags */
  240. len -= sizeof(struct virtio_net_hdr);
  241. nic->packetlen = len;
  242. memcpy(nic->packet, (char *)rx_buffer[token], nic->packetlen);
  243. /* add buffer to desc */
  244. list[0].addr = (char*)&rx_hdr[token];
  245. list[0].length = sizeof(struct virtio_net_hdr);
  246. list[1].addr = (char*)&rx_buffer[token];
  247. list[1].length = ETH_FRAME_LEN;
  248. vring_add_buf(RX_INDEX, list, 0, 2, token, 0);
  249. vring_kick(nic, RX_INDEX, 1);
  250. return 1;
  251. }
  252. /*
  253. *
  254. * virtnet_transmit
  255. *
  256. * Transmit a frame
  257. *
  258. */
  259. static void virtnet_transmit(struct nic *nic, const char *destaddr,
  260. unsigned int type, unsigned int len, const char *data)
  261. {
  262. struct vring_list list[2];
  263. /*
  264. * from http://www.etherboot.org/wiki/dev/devmanual :
  265. * "You do not need more than one transmit buffer."
  266. */
  267. /* FIXME: initialize header according to vp_get_features() */
  268. tx_virtio_hdr.flags = 0;
  269. tx_virtio_hdr.csum_offset = 0;
  270. tx_virtio_hdr.csum_start = 0;
  271. tx_virtio_hdr.gso_type = VIRTIO_NET_HDR_GSO_NONE;
  272. tx_virtio_hdr.gso_size = 0;
  273. tx_virtio_hdr.hdr_len = 0;
  274. /* add ethernet frame into vring */
  275. BUG_ON(len > sizeof(tx_eth_frame.data));
  276. memcpy(tx_eth_frame.hdr.dst_addr, destaddr, ETH_ALEN);
  277. memcpy(tx_eth_frame.hdr.src_addr, nic->node_addr, ETH_ALEN);
  278. tx_eth_frame.hdr.type = htons(type);
  279. memcpy(tx_eth_frame.data, data, len);
  280. list[0].addr = (char*)&tx_virtio_hdr;
  281. list[0].length = sizeof(struct virtio_net_hdr);
  282. list[1].addr = (char*)&tx_eth_frame;
  283. list[1].length = ETH_FRAME_LEN;
  284. vring_add_buf(TX_INDEX, list, 2, 0, 0, 0);
  285. vring_kick(nic, TX_INDEX, 1);
  286. /*
  287. * http://www.etherboot.org/wiki/dev/devmanual
  288. *
  289. * "You should ensure the packet is fully transmitted
  290. * before returning from this routine"
  291. */
  292. while (!vring_more_used(TX_INDEX)) {
  293. mb();
  294. udelay(10);
  295. }
  296. /* free desc */
  297. (void)vring_get_buf(TX_INDEX, NULL);
  298. }
  299. static void virtnet_irq(struct nic *nic __unused, irq_action_t action)
  300. {
  301. switch ( action ) {
  302. case DISABLE :
  303. vring_disable_cb(RX_INDEX);
  304. vring_disable_cb(TX_INDEX);
  305. break;
  306. case ENABLE :
  307. vring_enable_cb(RX_INDEX);
  308. vring_enable_cb(TX_INDEX);
  309. break;
  310. case FORCE :
  311. break;
  312. }
  313. }
  314. static void provide_buffers(struct nic *nic)
  315. {
  316. int i;
  317. struct vring_list list[2];
  318. for (i = 0; i < RX_BUF_NB; i++) {
  319. list[0].addr = (char*)&rx_hdr[i];
  320. list[0].length = sizeof(struct virtio_net_hdr);
  321. list[1].addr = (char*)&rx_buffer[i];
  322. list[1].length = ETH_FRAME_LEN;
  323. vring_add_buf(RX_INDEX, list, 0, 2, i, i);
  324. }
  325. /* nofify */
  326. vring_kick(nic, RX_INDEX, i);
  327. }
  328. static struct nic_operations virtnet_operations = {
  329. .connect = dummy_connect,
  330. .poll = virtnet_poll,
  331. .transmit = virtnet_transmit,
  332. .irq = virtnet_irq,
  333. };
  334. /*
  335. * virtnet_probe
  336. *
  337. * Look for a virtio network adapter
  338. *
  339. */
  340. static int virtnet_probe(struct nic *nic, struct pci_device *pci)
  341. {
  342. u32 features;
  343. int i;
  344. /* Mask the bit that says "this is an io addr" */
  345. nic->ioaddr = pci->ioaddr & ~3;
  346. /* Copy IRQ from PCI information */
  347. nic->irqno = pci->irq;
  348. printf("I/O address 0x%08x, IRQ #%d\n", nic->ioaddr, nic->irqno);
  349. adjust_pci_device(pci);
  350. vp_reset(nic);
  351. features = vp_get_features(nic);
  352. if (features & (1 << VIRTIO_NET_F_MAC)) {
  353. vp_get(nic, offsetof(struct virtio_net_config, mac),
  354. nic->node_addr, ETH_ALEN);
  355. printf("MAC address ");
  356. for (i = 0; i < ETH_ALEN; i++) {
  357. printf("%02x%c", nic->node_addr[i],
  358. (i == ETH_ALEN - 1) ? '\n' : ':');
  359. }
  360. }
  361. /* initialize emit/receive queue */
  362. for (i = 0; i < QUEUE_NB; i++) {
  363. free_head[i] = 0;
  364. last_used_idx[i] = 0;
  365. memset((char*)&queue[i], 0, sizeof(queue[i]));
  366. if (vp_find_vq(nic, i) == -1)
  367. printf("Cannot register queue #%d\n", i);
  368. }
  369. /* provide some receive buffers */
  370. provide_buffers(nic);
  371. /* define NIC interface */
  372. nic->nic_op = &virtnet_operations;
  373. /* driver is ready */
  374. vp_set_features(nic, features & (1 << VIRTIO_NET_F_MAC));
  375. vp_set_status(nic, VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);
  376. return 1;
  377. }
  378. static struct pci_device_id virtnet_nics[] = {
  379. PCI_ROM(0x1af4, 0x1000, "virtio-net", "Virtio Network Interface"),
  380. };
  381. PCI_DRIVER ( virtnet_driver, virtnet_nics, PCI_NO_CLASS );
  382. DRIVER ( "VIRTIO-NET", nic_driver, pci_driver, virtnet_driver,
  383. virtnet_probe, virtnet_disable );