PageRenderTime 33ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

/servers/lwip/driver.c

http://www.minix3.org/
C | 821 lines | 611 code | 163 blank | 47 comment | 122 complexity | 6b011c9ef457f0261175b0174cdfcc51 MD5 | raw file
Possible License(s): MIT, WTFPL, AGPL-1.0, BSD-3-Clause, GPL-3.0, LGPL-2.0, JSON, 0BSD
  1. /*
  2. * This file implements handling of meesagges send by drivers
  3. */
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <minix/ipc.h>
  7. #include <minix/com.h>
  8. #include <minix/sysutil.h>
  9. #include <minix/safecopies.h>
  10. #include <minix/netsock.h>
  11. #include <sys/ioc_net.h>
  12. #include <net/gen/in.h>
  13. #include <net/gen/ip_io.h>
  14. #include <net/gen/route.h>
  15. #include <net/gen/ether.h>
  16. #include <net/gen/eth_io.h>
  17. #include <lwip/pbuf.h>
  18. #include <lwip/netif.h>
  19. #include <netif/etharp.h>
  20. #include "proto.h"
  21. #include "driver.h"
  22. #if 0
  23. #define debug_drv_print(str, ...) printf("LWIP %s:%d : " str "\n", \
  24. __func__, __LINE__, ##__VA_ARGS__)
  25. #else
  26. #define debug_drv_print(...) debug_print(__VA_ARGS__)
  27. #endif
  28. #define RAW_BUF_SIZE (32 << 10)
  29. static struct nic devices[MAX_DEVS];
  30. static ip_addr_t ip_addr_none = { IPADDR_NONE };
  31. extern endpoint_t lwip_ep;
  32. void nic_assign_driver(const char * dev_type,
  33. unsigned dev_num,
  34. const char * driver_name,
  35. unsigned instance,
  36. int is_default)
  37. {
  38. struct nic * nic;
  39. if (strcmp(dev_type, "eth") != 0) {
  40. printf("LWIP : Cannot handle other than ethernet devices, "
  41. "ignoring '%s%d'\n", dev_type, dev_num);
  42. return;
  43. }
  44. nic = &devices[dev_num];
  45. snprintf(nic->name, NIC_NAME_LEN, "%s%d", dev_type, dev_num);
  46. nic->name[NIC_NAME_LEN - 1] = '\0';
  47. snprintf(nic->drv_name, DRV_NAME_LEN, "%s_%d", driver_name, instance);
  48. nic->drv_name[DRV_NAME_LEN - 1] = '\0';
  49. nic->is_default = is_default;
  50. nic->netif.name[0] = 'e';
  51. nic->netif.name[1] = 't';
  52. nic->netif.num = dev_num;
  53. debug_print("/dev/%s driven by %s default = %d",
  54. nic->name, nic->drv_name, is_default);
  55. }
  56. static struct nic * lookup_nic_by_drv_ep(endpoint_t ep)
  57. {
  58. int i;
  59. for (i = 0; i < MAX_DEVS; i++) {
  60. if (devices[i].drv_ep == ep)
  61. return &devices[i];
  62. }
  63. return NULL;
  64. }
  65. static struct nic * lookup_nic_by_drv_name(const char * name)
  66. {
  67. int i;
  68. for (i = 0; i < MAX_DEVS; i++) {
  69. if (strcmp(devices[i].drv_name, name) == 0)
  70. return &devices[i];
  71. }
  72. return NULL;
  73. }
  74. static struct nic * lookup_nic_default(void)
  75. {
  76. int i;
  77. for (i = 0; i < MAX_DEVS; i++) {
  78. if (devices[i].is_default)
  79. return &devices[i];
  80. }
  81. return NULL;
  82. }
  83. void nic_init_all(void)
  84. {
  85. int i;
  86. unsigned g;
  87. for (i = 0; i < MAX_DEVS; i++) {
  88. devices[i].drv_ep = NONE;
  89. devices[i].is_default = 0;
  90. if (cpf_getgrants(&devices[i].rx_iogrant, 1) != 1)
  91. panic("Cannot initialize grants");
  92. if (cpf_getgrants(&devices[i].rx_iovec[0].iov_grant, 1) != 1)
  93. panic("Cannot initialize grants");
  94. if (cpf_getgrants(&devices[i].tx_iogrant, 1) != 1)
  95. panic("Cannot initialize grants");
  96. for (g = 0; g < TX_IOVEC_NUM; g++) {
  97. cp_grant_id_t * gid = &devices[i].tx_iovec[g].iov_grant;
  98. if (cpf_getgrants(gid, 1) != 1)
  99. panic("Cannot initialize grants");
  100. }
  101. devices[i].raw_socket = NULL;
  102. }
  103. }
  104. static void driver_setup_read(struct nic * nic)
  105. {
  106. message m;
  107. debug_print("device /dev/%s", nic->name);
  108. //assert(nic->rx_pbuf == NULL);
  109. if (!(nic->rx_pbuf == NULL)) {
  110. panic("device /dev/%s rx_pbuf %p", nic->name, nic->rx_pbuf);
  111. }
  112. if (!(nic->rx_pbuf = pbuf_alloc(PBUF_RAW, ETH_MAX_PACK_SIZE + ETH_CRC_SIZE, PBUF_RAM)))
  113. panic("Cannot allocate rx pbuf");
  114. if (cpf_setgrant_direct(nic->rx_iovec[0].iov_grant,
  115. nic->drv_ep, (vir_bytes) nic->rx_pbuf->payload,
  116. nic->rx_pbuf->len, CPF_WRITE) != OK)
  117. panic("Failed to set grant");
  118. nic->rx_iovec[0].iov_size = nic->rx_pbuf->len;
  119. m.m_type = DL_READV_S;
  120. m.DL_COUNT = 1;
  121. m.DL_GRANT = nic->rx_iogrant;
  122. if (asynsend(nic->drv_ep, &m) != OK)
  123. panic("asynsend to the driver failed!");
  124. }
  125. static void nic_up(struct nic * nic, message * m)
  126. {
  127. memcpy(nic->netif.hwaddr, m->DL_HWADDR, NETIF_MAX_HWADDR_LEN);
  128. debug_print("device %s is up MAC : %02x:%02x:%02x:%02x:%02x:%02x",
  129. nic->name,
  130. nic->netif.hwaddr[0],
  131. nic->netif.hwaddr[1],
  132. nic->netif.hwaddr[2],
  133. nic->netif.hwaddr[3],
  134. nic->netif.hwaddr[4],
  135. nic->netif.hwaddr[5]);
  136. driver_setup_read(nic);
  137. netif_set_link_up(&nic->netif);
  138. netif_set_up(&nic->netif);
  139. }
  140. int driver_tx(struct nic * nic)
  141. {
  142. struct packet_q * pkt;
  143. unsigned len;
  144. message m;
  145. int err;
  146. debug_print("device /dev/%s", nic->name);
  147. assert(nic->tx_buffer);
  148. pkt = driver_tx_head(nic);
  149. if (pkt == NULL) {
  150. debug_print("no packets enqueued");
  151. return 0;
  152. }
  153. assert(pkt->buf_len <= nic->max_pkt_sz);
  154. if ((len = pkt->buf_len) < nic->min_pkt_sz)
  155. len = nic->min_pkt_sz;
  156. err = cpf_setgrant_direct(nic->tx_iovec[0].iov_grant,
  157. nic->drv_ep, (vir_bytes) pkt->buf,
  158. len, CPF_READ);
  159. debug_print("packet len %d", len);
  160. if (err != OK)
  161. panic("Failed to set grant");
  162. nic->tx_iovec[0].iov_size = len;
  163. if (cpf_setgrant_direct(nic->tx_iogrant, nic->drv_ep,
  164. (vir_bytes) &nic->tx_iovec,
  165. sizeof(iovec_s_t), CPF_READ) != OK)
  166. panic("Failed to set grant");
  167. m.m_type = DL_WRITEV_S;
  168. m.DL_COUNT = 1;
  169. m.DL_GRANT = nic->tx_iogrant;
  170. if (asynsend(nic->drv_ep, &m) != OK)
  171. panic("asynsend to the driver failed!");
  172. nic->state = DRV_SENDING;
  173. debug_print("packet sent to driver");
  174. return 1;
  175. }
  176. static void nic_pkt_sent(struct nic * nic)
  177. {
  178. debug_print("device /dev/%s", nic->name);
  179. assert(nic->state != DRV_IDLE);
  180. /* packet has been sent, we are not intereted anymore */
  181. driver_tx_dequeue(nic);
  182. /*
  183. * Try to transmit the next packet. Failure means that no packet is
  184. * enqueued and thus the device is entering idle state
  185. */
  186. if (!driver_tx(nic))
  187. nic->state = DRV_IDLE;
  188. }
  189. __unused static void print_pkt(unsigned char * pkt, int len)
  190. {
  191. int i = 0;
  192. printf("--- PKT ---\n");
  193. while (i < len) {
  194. int x;
  195. for (x = 0; x < 8 && i < len; x++, i++)
  196. printf("%02x ", pkt[i]);
  197. kputc(' ');
  198. for (x = 0; x < 8 && i < len; x++, i++)
  199. printf("%02x ", pkt[i]);
  200. kputc('\n');
  201. }
  202. printf("--- PKT END ---\n");
  203. }
  204. static int raw_receive(message * m,
  205. struct pbuf *pbuf)
  206. {
  207. struct pbuf * p;
  208. unsigned rem_len = m->COUNT;
  209. unsigned written = 0;
  210. int err;
  211. debug_print("user buffer size : %d\n", rem_len);
  212. for (p = pbuf; p && rem_len; p = p->next) {
  213. size_t cp_len;
  214. cp_len = (rem_len < p->len) ? rem_len : p->len;
  215. err = copy_to_user(m->m_source, p->payload, cp_len,
  216. (cp_grant_id_t) m->IO_GRANT,
  217. written);
  218. if (err != OK)
  219. return err;
  220. written += cp_len;
  221. rem_len -= cp_len;
  222. }
  223. debug_print("copied %d bytes\n", written);
  224. return written;
  225. }
  226. int raw_socket_input(struct pbuf * pbuf, struct nic * nic)
  227. {
  228. struct socket * sock;
  229. struct pbuf * pbuf_new;
  230. if ((sock = nic->raw_socket) == NULL)
  231. return 0;
  232. debug_print("socket num : %ld", get_sock_num(sock));
  233. if (sock->flags & SOCK_FLG_OP_PENDING) {
  234. int ret;
  235. /* we are resuming a suspended operation */
  236. ret = raw_receive(&sock->mess, pbuf);
  237. if (ret > 0) {
  238. sock_reply(sock, ret);
  239. sock->flags &= ~SOCK_FLG_OP_PENDING;
  240. return 0;
  241. } else {
  242. sock_reply(sock, ret);
  243. sock->flags &= ~SOCK_FLG_OP_PENDING;
  244. }
  245. }
  246. /* Do not enqueue more data than allowed */
  247. if (sock->recv_data_size > RAW_BUF_SIZE) {
  248. return 0;
  249. }
  250. /*
  251. * nobody is waiting for the data or an error occured above, we enqueue
  252. * the packet. We store a copy of this packet
  253. */
  254. pbuf_new = pbuf_alloc(PBUF_RAW, pbuf->tot_len, PBUF_RAM);
  255. if (pbuf_new == NULL) {
  256. debug_print("LWIP : cannot allocated new pbuf\n");
  257. return 0;
  258. }
  259. if (pbuf_copy(pbuf_new, pbuf) != ERR_OK) {
  260. debug_print("LWIP : cannot copy pbuf\n");
  261. return 0;
  262. }
  263. /*
  264. * If we didn't managed to enqueue the packet we report it as not
  265. * consumed
  266. */
  267. if (sock_enqueue_data(sock, pbuf_new, pbuf_new->tot_len) != OK) {
  268. pbuf_free(pbuf_new);
  269. }
  270. return 0;
  271. }
  272. static void nic_pkt_received(struct nic * nic, unsigned size)
  273. {
  274. assert(nic->netif.input);
  275. #if 0
  276. print_pkt((unsigned char *) nic->rx_pbuf->payload, 64 /*nic->rx_pbuf->len */);
  277. #endif
  278. assert(nic->rx_pbuf->tot_len == nic->rx_pbuf->len);
  279. nic->rx_pbuf->tot_len = nic->rx_pbuf->len = size - ETH_CRC_SIZE;
  280. nic->netif.input(nic->rx_pbuf, &nic->netif);
  281. nic->rx_pbuf = NULL;
  282. driver_setup_read(nic);
  283. }
  284. void driver_request(message * m)
  285. {
  286. struct nic * nic;
  287. if ((nic = lookup_nic_by_drv_ep(m->m_source)) == NULL) {
  288. printf("LWIP : request from unknown driver %d\n", m->m_source);
  289. return;
  290. }
  291. switch (m->m_type) {
  292. case DL_CONF_REPLY:
  293. if (m->DL_STAT == OK)
  294. nic_up(nic, m);
  295. break;
  296. case DL_TASK_REPLY:
  297. /*
  298. if (!(m->DL_FLAGS & DL_PACK_SEND) && !(m->DL_FLAGS & DL_PACK_RECV)) {
  299. printf("void reply from driver\n");
  300. break;
  301. }
  302. */
  303. if (m->DL_FLAGS & DL_PACK_SEND)
  304. nic_pkt_sent(nic);
  305. if (m->DL_FLAGS & DL_PACK_RECV)
  306. nic_pkt_received(nic, m->DL_COUNT);
  307. break;
  308. case DL_STAT_REPLY:
  309. break;
  310. default:
  311. printf("LWIP : unexpected request %d from driver %d\n",
  312. m->m_type, m->m_source);
  313. }
  314. }
  315. void driver_up(const char * label, endpoint_t ep)
  316. {
  317. struct nic * nic;
  318. nic = lookup_nic_by_drv_name(label);
  319. if (nic) {
  320. debug_print("LWIP : driver '%s' / %d is up for /dev/%s\n",
  321. label, ep, nic->name);
  322. nic->drv_ep = ep;
  323. } else
  324. printf("LWIP : WARNING unexpected driver '%s' up event\n",
  325. label);
  326. nic->state = DRV_IDLE;
  327. /*
  328. * FIXME
  329. *
  330. * We set the initial ip to 0.0.0.0 to make dhcpd broadcasing work
  331. * at the very begining. dhcp should use raw socket but it is a little
  332. * tricy in the current dhcp implementation
  333. */
  334. if (!netif_add(&nic->netif, (ip_addr_t *) &ip_addr_any, &ip_addr_none,
  335. &ip_addr_none, nic, ethernetif_init, ethernet_input)) {
  336. printf("LWIP : failed to add device /dev/%s\n", nic->name);
  337. nic->drv_ep = NONE;
  338. }
  339. if (nic->is_default)
  340. netif_set_default(&nic->netif);
  341. /* FIXME we support ethernet only, 2048 is safe */
  342. nic->tx_buffer = debug_malloc(2048);
  343. if (nic->tx_buffer == NULL)
  344. panic("Cannot allocate tx_buffer");
  345. /* prepare the RX grant once and forever */
  346. if (cpf_setgrant_direct(nic->rx_iogrant,
  347. nic->drv_ep,
  348. (vir_bytes) &nic->rx_iovec,
  349. 1 * sizeof(iovec_s_t), CPF_READ) != OK)
  350. panic("Failed to set grant");
  351. }
  352. static void raw_recv_free(__unused void * data)
  353. {
  354. pbuf_free((struct pbuf *) data);
  355. }
  356. static void nic_op_close(struct socket * sock, __unused message * m)
  357. {
  358. struct nic * nic = (struct nic *)sock->data;
  359. debug_drv_print("socket %d", get_sock_num(sock));
  360. sock_dequeue_data_all(sock, raw_recv_free);
  361. sock->ops = NULL;
  362. if (nic->raw_socket == sock) {
  363. nic->raw_socket = NULL;
  364. debug_drv_print("no active raw sock at %s", nic->name);
  365. }
  366. sock_reply_close(sock, OK);
  367. }
  368. static void nic_ioctl_set_conf(__unused struct socket * sock,
  369. struct nic * nic,
  370. message * m)
  371. {
  372. nwio_ipconf_t ipconf;
  373. int err;
  374. err = copy_from_user(m->m_source, &ipconf, sizeof(ipconf),
  375. (cp_grant_id_t) m->IO_GRANT, 0);
  376. if (err != OK)
  377. send_reply(m, err);
  378. if (ipconf.nwic_flags & NWIC_IPADDR_SET)
  379. netif_set_ipaddr(&nic->netif,
  380. (ip_addr_t *)&ipconf.nwic_ipaddr);
  381. if (ipconf.nwic_flags & NWIC_NETMASK_SET)
  382. netif_set_netmask(&nic->netif,
  383. (ip_addr_t *)&ipconf.nwic_netmask);
  384. nic->flags = ipconf.nwic_flags;
  385. if (nic->flags & NWEO_EN_BROAD)
  386. nic->netif.flags |= NETIF_FLAG_BROADCAST;
  387. send_reply(m, OK);
  388. }
  389. static void nic_ioctl_get_conf(__unused struct socket * sock,
  390. struct nic * nic,
  391. message * m)
  392. {
  393. nwio_ipconf_t ipconf;
  394. int err;
  395. ipconf.nwic_flags = nic->flags;
  396. ipconf.nwic_ipaddr = nic->netif.ip_addr.addr;
  397. ipconf.nwic_netmask = nic->netif.netmask.addr;
  398. ipconf.nwic_mtu = nic->netif.mtu;
  399. err = copy_to_user(m->m_source, &ipconf, sizeof(ipconf),
  400. (cp_grant_id_t) m->IO_GRANT, 0);
  401. if (err != OK)
  402. send_reply(m, err);
  403. send_reply(m, OK);
  404. }
  405. static void nic_ioctl_set_gateway(__unused struct socket * sock,
  406. struct nic * nic,
  407. message * m)
  408. {
  409. nwio_route_t route;
  410. int err;
  411. err = copy_from_user(m->m_source, &route, sizeof(route),
  412. (cp_grant_id_t) m->IO_GRANT, 0);
  413. if (err != OK)
  414. send_reply(m, err);
  415. netif_set_gw(&nic->netif, (ip_addr_t *)&route.nwr_gateway);
  416. send_reply(m, OK);
  417. }
  418. static void nic_ioctl_get_ethstat(__unused struct socket * sock,
  419. struct nic * nic,
  420. message * m)
  421. {
  422. int err;
  423. nwio_ethstat_t ethstat;
  424. debug_drv_print("device /dev/%s", nic->name);
  425. /*
  426. * The device is not up yet, there is nothing to report or it is not
  427. * an ethernet device
  428. */
  429. if (!nic->netif.flags & NETIF_FLAG_UP ||
  430. !(nic->netif.flags & (NETIF_FLAG_ETHERNET |
  431. NETIF_FLAG_ETHARP))) {
  432. printf("LWIP no such device FUCK\n");
  433. send_reply(m, ENODEV);
  434. return;
  435. }
  436. memset(&ethstat, 0, sizeof(ethstat));
  437. memcpy(&ethstat.nwes_addr, nic->netif.hwaddr, 6);
  438. err = copy_to_user(m->m_source, &ethstat, sizeof(ethstat),
  439. (cp_grant_id_t) m->IO_GRANT, 0);
  440. if (err != OK)
  441. send_reply(m, err);
  442. send_reply(m, OK);
  443. }
  444. static void nic_ioctl_set_ethopt(struct socket * sock,
  445. struct nic * nic,
  446. message * m)
  447. {
  448. int err;
  449. nwio_ethopt_t ethopt;
  450. assert(nic);
  451. if (!sock) {
  452. send_reply(m, EINVAL);
  453. return;
  454. }
  455. debug_drv_print("device /dev/%s", nic->name);
  456. /*
  457. * The device is not up yet, there is nothing to report or it is not
  458. * an ethernet device
  459. */
  460. if (!nic->netif.flags & NETIF_FLAG_UP ||
  461. !(nic->netif.flags & (NETIF_FLAG_ETHERNET |
  462. NETIF_FLAG_ETHARP))) {
  463. send_reply(m, ENODEV);
  464. return;
  465. }
  466. err = copy_from_user(m->m_source, &ethopt, sizeof(ethopt),
  467. (cp_grant_id_t) m->IO_GRANT, 0);
  468. if (err != OK)
  469. send_reply(m, err);
  470. /* we want to get data from this sock */
  471. if (ethopt.nweo_flags & NWEO_COPY) {
  472. if (nic->raw_socket) {
  473. send_reply(m, EBUSY);
  474. return;
  475. }
  476. nic->raw_socket = sock;
  477. debug_drv_print("active raw sock %d at %s",
  478. get_sock_num(sock), nic->name);
  479. }
  480. send_reply(m, OK);
  481. }
  482. static void nic_do_ioctl(struct socket * sock, struct nic * nic, message * m)
  483. {
  484. debug_print("device /dev/%s req %c %d %d",
  485. nic->name,
  486. (m->REQUEST >> 8) & 0xff,
  487. m->REQUEST & 0xff,
  488. (m->REQUEST >> 16) & _IOCPARM_MASK);
  489. debug_drv_print("socket %d", sock ? get_sock_num(sock) : -1);
  490. switch (m->REQUEST) {
  491. case NWIOSIPCONF:
  492. nic_ioctl_set_conf(sock, nic, m);
  493. break;
  494. case NWIOGIPCONF:
  495. nic_ioctl_get_conf(sock, nic, m);
  496. break;
  497. case NWIOSIPOROUTE:
  498. nic_ioctl_set_gateway(sock, nic, m);
  499. break;
  500. case NWIOGETHSTAT:
  501. nic_ioctl_get_ethstat(sock, nic, m);
  502. break;
  503. case NWIOSETHOPT:
  504. nic_ioctl_set_ethopt(sock, nic, m);
  505. break;
  506. default:
  507. send_reply(m, EBADIOCTL);
  508. return;
  509. }
  510. }
  511. void nic_default_ioctl(message *m)
  512. {
  513. struct nic * nic = lookup_nic_default();
  514. if (nic == NULL) {
  515. debug_print("No default nic, reporting error");
  516. send_reply(m, EBADIOCTL);
  517. return;
  518. }
  519. nic_do_ioctl(NULL, nic, m);
  520. }
  521. static void nic_op_ioctl(struct socket * sock, message * m, __unused int blk)
  522. {
  523. nic_do_ioctl(sock, (struct nic *)sock->data, m);
  524. }
  525. static void nic_op_read(struct socket * sock, message * m, int blk)
  526. {
  527. debug_drv_print("sock num %d", get_sock_num(sock));
  528. if (sock->recv_head) {
  529. /* data available receive immeditely */
  530. struct pbuf * pbuf;
  531. int ret;
  532. pbuf = sock->recv_head->data;
  533. ret = raw_receive(m, pbuf);
  534. if (ret > 0) {
  535. sock_dequeue_data(sock);
  536. sock->recv_data_size -= pbuf->tot_len;
  537. pbuf_free(pbuf);
  538. }
  539. sock_reply(sock, ret);
  540. } else if (!blk)
  541. send_reply(m, EAGAIN);
  542. else {
  543. /* store the message so we know how to reply */
  544. sock->mess = *m;
  545. /* operation is being processes */
  546. sock->flags |= SOCK_FLG_OP_PENDING;
  547. debug_print("no data to read, suspending");
  548. }
  549. }
  550. static void nic_op_write(struct socket * sock, message * m, __unused int blk)
  551. {
  552. int ret;
  553. struct pbuf * pbuf;
  554. struct nic * nic = (struct nic *)sock->data;
  555. assert(nic);
  556. debug_print("device %s data size %d", nic->name,
  557. get_sock_num(sock), m->COUNT);
  558. pbuf = pbuf_alloc(PBUF_RAW, m->COUNT, PBUF_RAM);
  559. if (!pbuf) {
  560. ret = ENOMEM;
  561. goto write_err;
  562. }
  563. if ((ret = copy_from_user(m->m_source, pbuf->payload, m->COUNT,
  564. (cp_grant_id_t) m->IO_GRANT, 0)) != OK) {
  565. pbuf_free(pbuf);
  566. goto write_err;
  567. }
  568. if ((ret = nic->netif.linkoutput(&nic->netif, pbuf) != ERR_OK)) {
  569. debug_print("raw linkoutput failed %d", ret);
  570. ret = EIO;
  571. } else
  572. ret = m->COUNT;
  573. pbuf_free(pbuf);
  574. write_err:
  575. sock_reply(sock, ret);
  576. }
  577. static struct sock_ops nic_ops = {
  578. .write = nic_op_write,
  579. .read = nic_op_read,
  580. .close = nic_op_close,
  581. .ioctl = nic_op_ioctl,
  582. .select = generic_op_select,
  583. .select_reply = generic_op_select_reply
  584. };
  585. void nic_open(message *m)
  586. {
  587. struct socket * sock;
  588. debug_print("device %d", m->DEVICE);
  589. if (m->DEVICE > MAX_DEVS || devices[m->DEVICE].drv_ep == NONE) {
  590. send_reply_open(m, ENODEV);
  591. return;
  592. }
  593. sock = get_unused_sock();
  594. if (sock == NULL) {
  595. send_reply(m, ENODEV);
  596. return;
  597. }
  598. if (sock->ops != NULL) {
  599. send_reply(m, EBUSY);
  600. return;
  601. }
  602. sock->ops = &nic_ops;
  603. sock->select_ep = NONE;
  604. sock->recv_data_size = 0;
  605. sock->data = &devices[m->DEVICE];
  606. send_reply_open(m, get_sock_num(sock));
  607. }
  608. static int driver_pkt_enqueue(struct packet_q ** head,
  609. struct packet_q ** tail,
  610. struct pbuf * pbuf)
  611. {
  612. struct packet_q * pkt;
  613. char * b;
  614. pkt = (struct packet_q *) malloc(sizeof(struct packet_q) + pbuf->tot_len);
  615. if (!pkt)
  616. return ENOMEM;
  617. pkt->next = NULL;
  618. pkt->buf_len = pbuf->tot_len;
  619. for (b = pkt->buf; pbuf; pbuf = pbuf->next) {
  620. memcpy(b, pbuf->payload, pbuf->len);
  621. b += pbuf->len;
  622. }
  623. if (*head == NULL)
  624. *head = *tail = pkt;
  625. else {
  626. (*tail)->next = pkt;
  627. *tail = pkt;
  628. }
  629. return OK;
  630. }
  631. int driver_tx_enqueue(struct nic * nic, struct pbuf * pbuf)
  632. {
  633. debug_print("device /dev/%s", nic->name);
  634. return driver_pkt_enqueue(&nic->tx_head, &nic->tx_tail, pbuf);
  635. }
  636. static void driver_pkt_dequeue(struct packet_q ** head,
  637. struct packet_q ** tail)
  638. {
  639. struct packet_q * pkt;
  640. /* we always dequeue only if there is something to dequeue */
  641. assert(*head);
  642. pkt = *head;
  643. if ((*head = pkt->next) == NULL)
  644. *tail = NULL;
  645. debug_free(pkt);
  646. }
  647. void driver_tx_dequeue(struct nic * nic)
  648. {
  649. debug_print("device /dev/%s", nic->name);
  650. driver_pkt_dequeue(&nic->tx_head, &nic->tx_tail);
  651. }
  652. struct packet_q * driver_tx_head(struct nic * nic)
  653. {
  654. debug_print("device /dev/%s", nic->name);
  655. if (!nic->tx_head)
  656. return NULL;
  657. return nic->tx_head;
  658. }