net.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769
  1. /*
  2. * Copyright (C) 2006-2009, 2011 Free Software Foundation
  3. *
  4. * This program is free software ; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation ; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY ; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with the program ; if not, write to the Free Software
  16. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #include <sys/types.h>
  19. #include <mach/mig_errors.h>
  20. #include <kern/kalloc.h>
  21. #include <ipc/ipc_port.h>
  22. #include <ipc/ipc_space.h>
  23. #include <vm/vm_kern.h>
  24. #include <device/device_types.h>
  25. #include <device/device_port.h>
  26. #include <device/if_hdr.h>
  27. #include <device/if_ether.h>
  28. #include <device/net_io.h>
  29. #include <device/device_reply.user.h>
  30. #include <device/device_emul.h>
  31. #include <device/ds_routines.h>
  32. #include <intel/pmap.h>
  33. #include <xen/public/io/netif.h>
  34. #include <xen/public/memory.h>
  35. #include <string.h>
  36. #include <util/atoi.h>
  37. #include "evt.h"
  38. #include "store.h"
  39. #include "net.h"
  40. #include "grant.h"
  41. #include "ring.h"
  42. #include "time.h"
  43. #include "xen.h"
  44. /* Hypervisor part */
  45. #define ADDRESS_SIZE 6
  46. #define WINDOW __RING_SIZE((netif_rx_sring_t*)0, PAGE_SIZE)
  47. /* Are we paranoid enough to not leak anything to backend? */
  48. static const int paranoia = 0;
  49. struct net_data {
  50. struct device device;
  51. struct ifnet ifnet;
  52. int open_count;
  53. char *backend;
  54. domid_t domid;
  55. char *vif;
  56. u_char address[ADDRESS_SIZE];
  57. int handle;
  58. ipc_port_t port;
  59. netif_tx_front_ring_t tx;
  60. netif_rx_front_ring_t rx;
  61. void *rx_buf[WINDOW];
  62. grant_ref_t rx_buf_gnt[WINDOW];
  63. unsigned long rx_buf_pfn[WINDOW];
  64. int rx_copy;
  65. evtchn_port_t evt;
  66. simple_lock_data_t lock;
  67. simple_lock_data_t pushlock;
  68. };
  69. static int n_vifs;
  70. static struct net_data *vif_data;
  71. struct device_emulation_ops hyp_net_emulation_ops;
  72. int hextoi(char *cp, int *nump)
  73. {
  74. int number;
  75. char *original;
  76. char c;
  77. original = cp;
  78. for (number = 0, c = *cp | 0x20; (('0' <= c) && (c <= '9')) || (('a' <= c) && (c <= 'f')); c = *(++cp)) {
  79. number *= 16;
  80. if (c <= '9')
  81. number += c - '0';
  82. else
  83. number += c - 'a' + 10;
  84. }
  85. if (original == cp)
  86. *nump = -1;
  87. else
  88. *nump = number;
  89. return(cp - original);
  90. }
  91. static void enqueue_rx_buf(struct net_data *nd, int number) {
  92. unsigned reqn = nd->rx.req_prod_pvt++;
  93. netif_rx_request_t *req = RING_GET_REQUEST(&nd->rx, reqn);
  94. grant_ref_t gref;
  95. assert(number < WINDOW);
  96. req->id = number;
  97. if (nd->rx_copy) {
  98. /* Let domD write the data */
  99. gref = hyp_grant_give(nd->domid, nd->rx_buf_pfn[number], 0);
  100. } else {
  101. /* Accept pages from domD */
  102. gref = hyp_grant_accept_transfer(nd->domid, nd->rx_buf_pfn[number]);
  103. /* give back page */
  104. hyp_free_page(nd->rx_buf_pfn[number], nd->rx_buf[number]);
  105. }
  106. req->gref = nd->rx_buf_gnt[number] = gref;
  107. }
  108. static int recompute_checksum(void *data, int len) {
  109. uint16_t *header16 = data;
  110. uint8_t *header8 = data;
  111. unsigned length, i;
  112. uint32_t checksum = 0;
  113. /* IPv4 header length */
  114. length = (header8[0] & 0xf) * 4;
  115. if (length < 20)
  116. /* Too small for an IP header16 */
  117. return -1;
  118. if (length > len)
  119. /* Does not fit in the ethernet frame */
  120. return -1;
  121. /* Compute IP header checksum */
  122. header16[5] = 0;
  123. for (i = 0; i < length/2; i++)
  124. checksum += ntohs(header16[i]);
  125. while (checksum >> 16)
  126. checksum = (checksum & 0xffff) + (checksum >> 16);
  127. header16[5] = htons(~checksum);
  128. if (header8[9] == 6) {
  129. /* Need to fix TCP checksum as well */
  130. uint16_t *tcp_header16 = header16 + length/2;
  131. uint8_t *tcp_header8 = header8 + length;
  132. unsigned tcp_length = ntohs(header16[1]) - length;
  133. /* Pseudo IP header */
  134. checksum = ntohs(header16[6]) + ntohs(header16[7]) +
  135. ntohs(header16[8]) + ntohs(header16[9]) +
  136. header8[9] + tcp_length;
  137. tcp_header16[8] = 0;
  138. for (i = 0; i < tcp_length / 2; i++)
  139. checksum += ntohs(tcp_header16[i]);
  140. if (tcp_length & 1)
  141. checksum += tcp_header8[tcp_length-1] << 8;
  142. while (checksum >> 16)
  143. checksum = (checksum & 0xffff) + (checksum >> 16);
  144. tcp_header16[8] = htons(~checksum);
  145. } else if (header8[9] == 17) {
  146. /* Drop any bogus checksum */
  147. uint16_t *udp_header16 = header16 + length/2;
  148. udp_header16[3] = 0;
  149. }
  150. return 0;
  151. }
  152. static void hyp_net_intr(int unit) {
  153. ipc_kmsg_t kmsg;
  154. struct ether_header *eh;
  155. struct packet_header *ph;
  156. netif_rx_response_t *rx_rsp;
  157. netif_tx_response_t *tx_rsp;
  158. void *data;
  159. int len, more;
  160. struct net_data *nd = &vif_data[unit];
  161. simple_lock(&nd->lock);
  162. if ((nd->rx.sring->rsp_prod - nd->rx.rsp_cons) >= (WINDOW*3)/4)
  163. printf("window %ld a bit small!\n", WINDOW);
  164. more = RING_HAS_UNCONSUMED_RESPONSES(&nd->rx);
  165. while (more) {
  166. rmb(); /* make sure we see responses */
  167. rx_rsp = RING_GET_RESPONSE(&nd->rx, nd->rx.rsp_cons++);
  168. unsigned number = rx_rsp->id;
  169. assert(number < WINDOW);
  170. if (nd->rx_copy) {
  171. hyp_grant_takeback(nd->rx_buf_gnt[number]);
  172. } else {
  173. unsigned long mfn = hyp_grant_finish_transfer(nd->rx_buf_gnt[number]);
  174. #ifdef MACH_PSEUDO_PHYS
  175. mfn_list[nd->rx_buf_pfn[number]] = mfn;
  176. #endif /* MACH_PSEUDO_PHYS */
  177. pmap_map_mfn(nd->rx_buf[number], mfn);
  178. }
  179. kmsg = net_kmsg_get();
  180. if (!kmsg)
  181. /* gasp! Drop */
  182. goto drop;
  183. if (rx_rsp->status <= 0)
  184. switch (rx_rsp->status) {
  185. case NETIF_RSP_DROPPED:
  186. printf("Packet dropped\n");
  187. goto drop_kmsg;
  188. case NETIF_RSP_ERROR:
  189. printf("Packet error\n");
  190. goto drop_kmsg;
  191. case 0:
  192. printf("nul packet\n");
  193. goto drop_kmsg;
  194. default:
  195. printf("Unknown error %d\n", rx_rsp->status);
  196. goto drop_kmsg;
  197. }
  198. data = nd->rx_buf[number] + rx_rsp->offset;
  199. len = rx_rsp->status;
  200. if (rx_rsp->flags & NETRXF_csum_blank) {
  201. struct ether_header *ether = data;
  202. if (!(rx_rsp->flags & NETRXF_data_validated)) {
  203. printf("packet with no checksum and not validated, dropping it\n");
  204. goto drop_kmsg;
  205. }
  206. /* TODO: rather tell pfinet to ignore checksums */
  207. if (ntohs(ether->ether_type) != 0x0800) {
  208. printf("packet with no checksum and not IPv4, dropping it\n");
  209. goto drop_kmsg;
  210. }
  211. if (recompute_checksum(data + sizeof(*ether), len - sizeof(*ether)))
  212. goto drop_kmsg;
  213. }
  214. eh = (void*) (net_kmsg(kmsg)->header);
  215. ph = (void*) (net_kmsg(kmsg)->packet);
  216. memcpy(eh, data, sizeof (struct ether_header));
  217. memcpy(ph + 1, data + sizeof (struct ether_header), len - sizeof(struct ether_header));
  218. RING_FINAL_CHECK_FOR_RESPONSES(&nd->rx, more);
  219. enqueue_rx_buf(nd, number);
  220. ph->type = eh->ether_type;
  221. ph->length = len - sizeof(struct ether_header) + sizeof (struct packet_header);
  222. net_kmsg(kmsg)->sent = FALSE; /* Mark packet as received. */
  223. net_packet(&nd->ifnet, kmsg, ph->length, ethernet_priority(kmsg));
  224. continue;
  225. drop_kmsg:
  226. net_kmsg_put(kmsg);
  227. drop:
  228. RING_FINAL_CHECK_FOR_RESPONSES(&nd->rx, more);
  229. enqueue_rx_buf(nd, number);
  230. }
  231. /* commit new requests */
  232. int notify;
  233. wmb(); /* make sure it sees requests */
  234. RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&nd->rx, notify);
  235. if (notify)
  236. hyp_event_channel_send(nd->evt);
  237. /* Now the tx side */
  238. more = RING_HAS_UNCONSUMED_RESPONSES(&nd->tx);
  239. spl_t s = splsched ();
  240. while (more) {
  241. rmb(); /* make sure we see responses */
  242. tx_rsp = RING_GET_RESPONSE(&nd->tx, nd->tx.rsp_cons++);
  243. switch (tx_rsp->status) {
  244. case NETIF_RSP_DROPPED:
  245. printf("Packet dropped\n");
  246. break;
  247. case NETIF_RSP_ERROR:
  248. printf("Packet error\n");
  249. break;
  250. case NETIF_RSP_OKAY:
  251. break;
  252. default:
  253. printf("Unknown error %d\n", tx_rsp->status);
  254. break;
  255. }
  256. thread_wakeup((event_t) hyp_grant_address(tx_rsp->id));
  257. thread_wakeup_one(nd);
  258. RING_FINAL_CHECK_FOR_RESPONSES(&nd->tx, more);
  259. }
  260. splx(s);
  261. simple_unlock(&nd->lock);
  262. }
  263. #define VIF_PATH "device/vif"
  264. void hyp_net_init(void) {
  265. char **vifs, **vif;
  266. char *c;
  267. int i;
  268. int n;
  269. int grant;
  270. char port_name[10];
  271. domid_t domid;
  272. evtchn_port_t evt;
  273. hyp_store_transaction_t t;
  274. vm_offset_t addr;
  275. struct net_data *nd;
  276. struct ifnet *ifp;
  277. netif_tx_sring_t *tx_ring;
  278. netif_rx_sring_t *rx_ring;
  279. vifs = hyp_store_ls(0, 1, VIF_PATH);
  280. if (!vifs) {
  281. printf("eth: No net device (%s). Hoping you don't need any\n", hyp_store_error);
  282. n_vifs = 0;
  283. return;
  284. }
  285. n = 0;
  286. for (vif = vifs; *vif; vif++)
  287. n++;
  288. vif_data = (void*) kalloc(n * sizeof(*vif_data));
  289. if (!vif_data) {
  290. printf("eth: No memory room for VIF\n");
  291. n_vifs = 0;
  292. return;
  293. }
  294. n_vifs = n;
  295. for (n = 0; n < n_vifs; n++) {
  296. nd = &vif_data[n];
  297. mach_atoi((u_char *) vifs[n], &nd->handle);
  298. if (nd->handle == MACH_ATOI_DEFAULT)
  299. continue;
  300. nd->open_count = -2;
  301. nd->vif = vifs[n];
  302. /* Get domain id of frontend driver. */
  303. i = hyp_store_read_int(0, 5, VIF_PATH, "/", vifs[n], "/", "backend-id");
  304. if (i == -1)
  305. panic("eth: couldn't read frontend domid of VIF %s (%s)",vifs[n], hyp_store_error);
  306. nd->domid = domid = i;
  307. do {
  308. t = hyp_store_transaction_start();
  309. /* Get a page for tx_ring */
  310. if ((addr = vm_page_grab_phys_addr()) == -1)
  311. panic("eth: couldn't allocate space for store tx_ring");
  312. tx_ring = (void*) phystokv(addr);
  313. SHARED_RING_INIT(tx_ring);
  314. FRONT_RING_INIT(&nd->tx, tx_ring, PAGE_SIZE);
  315. grant = hyp_grant_give(domid, atop(addr), 0);
  316. /* and give it to backend. */
  317. i = sprintf(port_name, "%d", grant);
  318. c = hyp_store_write(t, port_name, 5, VIF_PATH, "/", vifs[n], "/", "tx-ring-ref");
  319. if (!c)
  320. panic("eth: couldn't store tx_ring reference for VIF %s (%s)", vifs[n], hyp_store_error);
  321. kfree((vm_offset_t) c, strlen(c)+1);
  322. /* Get a page for rx_ring */
  323. if ((addr = vm_page_grab_phys_addr()) == -1)
  324. panic("eth: couldn't allocate space for store tx_ring");
  325. rx_ring = (void*) phystokv(addr);
  326. SHARED_RING_INIT(rx_ring);
  327. FRONT_RING_INIT(&nd->rx, rx_ring, PAGE_SIZE);
  328. grant = hyp_grant_give(domid, atop(addr), 0);
  329. /* and give it to backend. */
  330. i = sprintf(port_name, "%d", grant);
  331. c = hyp_store_write(t, port_name, 5, VIF_PATH, "/", vifs[n], "/", "rx-ring-ref");
  332. if (!c)
  333. panic("eth: couldn't store rx_ring reference for VIF %s (%s)", vifs[n], hyp_store_error);
  334. kfree((vm_offset_t) c, strlen(c)+1);
  335. /* tell we need csums. */
  336. c = hyp_store_write(t, "1", 5, VIF_PATH, "/", vifs[n], "/", "feature-no-csum-offload");
  337. if (!c)
  338. panic("eth: couldn't store feature-no-csum-offload reference for VIF %s (%s)", vifs[n], hyp_store_error);
  339. kfree((vm_offset_t) c, strlen(c)+1);
  340. /* Allocate an event channel and give it to backend. */
  341. nd->evt = evt = hyp_event_channel_alloc(domid);
  342. i = sprintf(port_name, "%u", evt);
  343. c = hyp_store_write(t, port_name, 5, VIF_PATH, "/", vifs[n], "/", "event-channel");
  344. if (!c)
  345. panic("eth: couldn't store event channel for VIF %s (%s)", vifs[n], hyp_store_error);
  346. kfree((vm_offset_t) c, strlen(c)+1);
  347. c = hyp_store_write(t, hyp_store_state_initialized, 5, VIF_PATH, "/", vifs[n], "/", "state");
  348. if (!c)
  349. panic("eth: couldn't store state for VIF %s (%s)", vifs[n], hyp_store_error);
  350. kfree((vm_offset_t) c, strlen(c)+1);
  351. } while ((!hyp_store_transaction_stop(t)));
  352. /* TODO randomly wait? */
  353. c = hyp_store_read(0, 5, VIF_PATH, "/", vifs[n], "/", "backend");
  354. if (!c)
  355. panic("eth: couldn't get path to VIF %s backend (%s)", vifs[n], hyp_store_error);
  356. nd->backend = c;
  357. while(1) {
  358. i = hyp_store_read_int(0, 3, nd->backend, "/", "state");
  359. if (i == MACH_ATOI_DEFAULT)
  360. panic("can't read state from %s", nd->backend);
  361. if (i == XenbusStateInitWait)
  362. break;
  363. hyp_yield();
  364. }
  365. c = hyp_store_read(0, 3, nd->backend, "/", "mac");
  366. if (!c)
  367. panic("eth: couldn't get VIF %s's mac (%s)", vifs[n], hyp_store_error);
  368. for (i=0; ; i++) {
  369. int val;
  370. hextoi(&c[3*i], &val);
  371. if (val == -1)
  372. panic("eth: couldn't understand %dth number of VIF %s's mac %s", i, vifs[n], c);
  373. nd->address[i] = val;
  374. if (i==ADDRESS_SIZE-1)
  375. break;
  376. if (c[3*i+2] != ':')
  377. panic("eth: couldn't understand %dth separator of VIF %s's mac %s", i, vifs[n], c);
  378. }
  379. kfree((vm_offset_t) c, strlen(c)+1);
  380. printf("eth%d: dom%d's VIF %s ", n, domid, vifs[n]);
  381. for (i=0; ; i++) {
  382. printf("%02x", nd->address[i]);
  383. if (i==ADDRESS_SIZE-1)
  384. break;
  385. printf(":");
  386. }
  387. printf("\n");
  388. nd->rx_copy = hyp_store_read_int(0, 3, nd->backend, "/", "feature-rx-copy");
  389. if (nd->rx_copy == 1) {
  390. c = hyp_store_write(0, "1", 5, VIF_PATH, "/", vifs[n], "/", "request-rx-copy");
  391. if (!c)
  392. panic("eth: couldn't request rx copy feature for VIF %s (%s)", vifs[n], hyp_store_error);
  393. } else
  394. nd->rx_copy = 0;
  395. c = hyp_store_write(0, hyp_store_state_connected, 5, VIF_PATH, "/", nd->vif, "/", "state");
  396. if (!c)
  397. panic("couldn't store state for eth%d (%s)", nd - vif_data, hyp_store_error);
  398. kfree((vm_offset_t) c, strlen(c)+1);
  399. while(1) {
  400. i = hyp_store_read_int(0, 3, nd->backend, "/", "state");
  401. if (i == MACH_ATOI_DEFAULT)
  402. panic("can't read state from %s", nd->backend);
  403. if (i == XenbusStateConnected)
  404. break;
  405. hyp_yield();
  406. }
  407. /* Get a page for packet reception */
  408. for (i= 0; i<WINDOW; i++) {
  409. if ((addr = vm_page_grab_phys_addr()) == -1)
  410. panic("eth: couldn't allocate space for store tx_ring");
  411. nd->rx_buf[i] = (void*)phystokv(addr);
  412. nd->rx_buf_pfn[i] = atop(addr);
  413. if (!nd->rx_copy) {
  414. if (hyp_do_update_va_mapping(kvtolin(nd->rx_buf[i]), 0, UVMF_INVLPG|UVMF_ALL))
  415. panic("eth: couldn't clear rx kv buf %d at %p", i, addr);
  416. }
  417. /* and enqueue it to backend. */
  418. enqueue_rx_buf(nd, i);
  419. }
  420. int notify;
  421. wmb(); /* make sure it sees requests */
  422. RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&nd->rx, notify);
  423. if (notify)
  424. hyp_event_channel_send(nd->evt);
  425. nd->open_count = -1;
  426. nd->device.emul_ops = &hyp_net_emulation_ops;
  427. nd->device.emul_data = nd;
  428. simple_lock_init(&nd->lock);
  429. simple_lock_init(&nd->pushlock);
  430. ifp = &nd->ifnet;
  431. ifp->if_unit = n;
  432. ifp->if_flags = IFF_UP | IFF_RUNNING;
  433. ifp->if_header_size = 14;
  434. ifp->if_header_format = HDR_ETHERNET;
  435. /* Set to the maximum that we can handle in device_write. */
  436. ifp->if_mtu = PAGE_SIZE - ifp->if_header_size;
  437. ifp->if_address_size = ADDRESS_SIZE;
  438. ifp->if_address = (void*) nd->address;
  439. if_init_queues (ifp);
  440. /* Now we can start receiving */
  441. hyp_evt_handler(evt, hyp_net_intr, n, SPL6);
  442. }
  443. }
  444. static ipc_port_t
  445. dev_to_port(void *d)
  446. {
  447. struct net_data *b = d;
  448. if (!d)
  449. return IP_NULL;
  450. return ipc_port_make_send(b->port);
  451. }
  452. static int
  453. device_close(void *devp)
  454. {
  455. struct net_data *nd = devp;
  456. if (--nd->open_count < 0)
  457. panic("too many closes on eth%d", nd - vif_data);
  458. printf("close, eth%d count %d\n",nd-vif_data,nd->open_count);
  459. if (nd->open_count)
  460. return 0;
  461. ipc_kobject_set(nd->port, IKO_NULL, IKOT_NONE);
  462. ipc_port_dealloc_kernel(nd->port);
  463. return 0;
  464. }
  465. static io_return_t
  466. device_open (ipc_port_t reply_port, mach_msg_type_name_t reply_port_type,
  467. dev_mode_t mode, char *name, device_t *devp /* out */)
  468. {
  469. int i, n;
  470. ipc_port_t port, notify;
  471. struct net_data *nd;
  472. if (name[0] != 'e' || name[1] != 't' || name[2] != 'h' || name[3] < '0' || name[3] > '9')
  473. return D_NO_SUCH_DEVICE;
  474. i = mach_atoi((u_char *) &name[3], &n);
  475. if (n == MACH_ATOI_DEFAULT)
  476. return D_NO_SUCH_DEVICE;
  477. if (name[3 + i])
  478. return D_NO_SUCH_DEVICE;
  479. if (n >= n_vifs)
  480. return D_NO_SUCH_DEVICE;
  481. nd = &vif_data[n];
  482. if (nd->open_count == -2)
  483. /* couldn't be initialized */
  484. return D_NO_SUCH_DEVICE;
  485. if (nd->open_count >= 0) {
  486. *devp = &nd->device ;
  487. nd->open_count++ ;
  488. printf("re-open, eth%d count %d\n",nd-vif_data,nd->open_count);
  489. return D_SUCCESS;
  490. }
  491. nd->open_count = 1;
  492. printf("eth%d count %d\n",nd-vif_data,nd->open_count);
  493. port = ipc_port_alloc_kernel();
  494. if (port == IP_NULL) {
  495. device_close (nd);
  496. return KERN_RESOURCE_SHORTAGE;
  497. }
  498. nd->port = port;
  499. *devp = &nd->device;
  500. ipc_kobject_set (port, (ipc_kobject_t) &nd->device, IKOT_DEVICE);
  501. notify = ipc_port_make_sonce (nd->port);
  502. ip_lock (nd->port);
  503. ipc_port_nsrequest (nd->port, 1, notify, &notify);
  504. assert (notify == IP_NULL);
  505. if (IP_VALID (reply_port))
  506. ds_device_open_reply (reply_port, reply_port_type, D_SUCCESS, dev_to_port(nd));
  507. else
  508. device_close(nd);
  509. return MIG_NO_REPLY;
  510. }
  511. static io_return_t
  512. device_write(void *d, ipc_port_t reply_port,
  513. mach_msg_type_name_t reply_port_type, dev_mode_t mode,
  514. recnum_t bn, io_buf_ptr_t data, unsigned int count,
  515. int *bytes_written)
  516. {
  517. vm_map_copy_t copy = (vm_map_copy_t) data;
  518. grant_ref_t gref;
  519. struct net_data *nd = d;
  520. struct ifnet *ifp = &nd->ifnet;
  521. netif_tx_request_t *req;
  522. unsigned reqn;
  523. vm_offset_t buffer;
  524. char *map_data;
  525. vm_offset_t map_addr;
  526. vm_size_t map_size;
  527. kern_return_t kr;
  528. /* The maximum that we can handle. */
  529. assert(ifp->if_header_size + ifp->if_mtu <= PAGE_SIZE);
  530. if (count < ifp->if_header_size ||
  531. count > ifp->if_header_size + ifp->if_mtu)
  532. return D_INVALID_SIZE;
  533. assert(copy->type == VM_MAP_COPY_PAGE_LIST);
  534. assert(copy->cpy_npages <= 2);
  535. assert(copy->cpy_npages >= 1);
  536. kr = kmem_alloc(device_io_map, &buffer, count);
  537. if (kr != KERN_SUCCESS)
  538. return kr;
  539. kr = kmem_io_map_copyout(device_io_map, (vm_offset_t *)&map_data,
  540. &map_addr, &map_size, copy, count);
  541. if (kr != KERN_SUCCESS) {
  542. kmem_free(device_io_map, buffer, count);
  543. return kr;
  544. }
  545. memcpy((void *)buffer, map_data, count);
  546. kmem_io_map_deallocate(device_io_map, map_addr, map_size);
  547. /* allocate a request */
  548. spl_t spl = splimp();
  549. while (1) {
  550. simple_lock(&nd->lock);
  551. if (!RING_FULL(&nd->tx))
  552. break;
  553. thread_sleep(nd, &nd->lock, FALSE);
  554. }
  555. mb();
  556. reqn = nd->tx.req_prod_pvt++;;
  557. simple_lock(&nd->pushlock);
  558. simple_unlock(&nd->lock);
  559. (void) splx(spl);
  560. req = RING_GET_REQUEST(&nd->tx, reqn);
  561. req->gref = gref = hyp_grant_give(nd->domid, atop(kvtophys(buffer)), 1);
  562. req->offset = 0;
  563. req->flags = 0;
  564. req->id = gref;
  565. req->size = count;
  566. assert_wait(hyp_grant_address(gref), FALSE);
  567. int notify;
  568. wmb(); /* make sure it sees requests */
  569. RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&nd->tx, notify);
  570. if (notify)
  571. hyp_event_channel_send(nd->evt);
  572. simple_unlock(&nd->pushlock);
  573. thread_block(NULL);
  574. hyp_grant_takeback(gref);
  575. /* Send packet to filters. */
  576. {
  577. struct packet_header *packet;
  578. struct ether_header *header;
  579. ipc_kmsg_t kmsg;
  580. kmsg = net_kmsg_get ();
  581. if (kmsg != IKM_NULL)
  582. {
  583. /* Suitable for Ethernet only. */
  584. header = (struct ether_header *) (net_kmsg (kmsg)->header);
  585. packet = (struct packet_header *) (net_kmsg (kmsg)->packet);
  586. memcpy (header, (void*)buffer, sizeof (struct ether_header));
  587. /* packet is prefixed with a struct packet_header,
  588. see include/device/net_status.h. */
  589. memcpy (packet + 1, (void*)buffer + sizeof (struct ether_header),
  590. count - sizeof (struct ether_header));
  591. packet->length = count - sizeof (struct ether_header)
  592. + sizeof (struct packet_header);
  593. packet->type = header->ether_type;
  594. net_kmsg (kmsg)->sent = TRUE; /* Mark packet as sent. */
  595. spl_t s = splimp ();
  596. net_packet (&nd->ifnet, kmsg, packet->length,
  597. ethernet_priority (kmsg));
  598. splx (s);
  599. }
  600. }
  601. kmem_free(device_io_map, buffer, count);
  602. vm_map_copy_discard (copy);
  603. *bytes_written = count;
  604. if (IP_VALID(reply_port))
  605. ds_device_write_reply (reply_port, reply_port_type, 0, count);
  606. return MIG_NO_REPLY;
  607. }
  608. static io_return_t
  609. device_get_status(void *d, dev_flavor_t flavor, dev_status_t status,
  610. mach_msg_type_number_t *status_count)
  611. {
  612. struct net_data *nd = d;
  613. return net_getstat (&nd->ifnet, flavor, status, status_count);
  614. }
  615. static io_return_t
  616. device_set_status(void *d, dev_flavor_t flavor, dev_status_t status,
  617. mach_msg_type_number_t count)
  618. {
  619. struct net_data *nd = d;
  620. switch (flavor)
  621. {
  622. default:
  623. printf("TODO: net_%s(%p, 0x%x)\n", __func__, nd, flavor);
  624. return D_INVALID_OPERATION;
  625. }
  626. return D_SUCCESS;
  627. }
  628. static io_return_t
  629. device_set_filter(void *d, ipc_port_t port, int priority,
  630. filter_t * filter, unsigned filter_count)
  631. {
  632. struct net_data *nd = d;
  633. if (!nd)
  634. return D_NO_SUCH_DEVICE;
  635. return net_set_filter (&nd->ifnet, port, priority, filter, filter_count);
  636. }
  637. struct device_emulation_ops hyp_net_emulation_ops = {
  638. NULL, /* dereference */
  639. NULL, /* deallocate */
  640. dev_to_port,
  641. device_open,
  642. device_close,
  643. device_write,
  644. NULL, /* write_inband */
  645. NULL,
  646. NULL, /* read_inband */
  647. device_set_status, /* set_status */
  648. device_get_status,
  649. device_set_filter, /* set_filter */
  650. NULL, /* map */
  651. NULL, /* no_senders */
  652. NULL, /* write_trap */
  653. NULL, /* writev_trap */
  654. };