voicebus_net.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /*
  2. * Voicebus network debug interface
  3. *
  4. * Written by Shaun Ruffell <sruffell@digium.com>
  5. *
  6. * Copyright (C) 2010 Digium, Inc.
  7. *
  8. * All rights reserved.
  9. * VoiceBus is a registered trademark of Digium.
  10. *
  11. */
  12. /*
  13. * See http://www.asterisk.org for more information about
  14. * the Asterisk project. Please do not directly contact
  15. * any of the maintainers of this project for assistance;
  16. * the project provides a web site, mailing lists and IRC
  17. * channels for your use.
  18. *
  19. * This program is free software, distributed under the terms of
  20. * the GNU General Public License Version 2 as published by the
  21. * Free Software Foundation. See the LICENSE file included with
  22. * this program for more details.
  23. */
  24. #include <linux/version.h>
  25. #include <linux/kernel.h>
  26. #include <linux/pci.h>
  27. #include <dahdi/kernel.h>
  28. #include "voicebus.h"
  29. #include "voicebus_net.h"
  30. #ifdef VOICEBUS_NET_DEBUG
  31. struct voicebus_netdev_priv {
  32. struct voicebus *vb;
  33. };
  34. static inline struct voicebus *
  35. voicebus_from_netdev(struct net_device *netdev)
  36. {
  37. struct voicebus_netdev_priv *priv;
  38. priv = netdev_priv(netdev);
  39. return priv->vb;
  40. }
  41. static void *
  42. skb_to_vbb(struct voicebus *vb, struct sk_buff *skb)
  43. {
  44. int res;
  45. void *vbb;
  46. const int COMMON_HEADER = 30;
  47. if (skb->len != (VOICEBUS_SFRAME_SIZE + COMMON_HEADER)) {
  48. dev_warn(&vb->pdev->dev, "Packet of length %d is not the "
  49. "required %d.\n", skb->len,
  50. VOICEBUS_SFRAME_SIZE + COMMON_HEADER);
  51. return NULL;
  52. }
  53. vbb = voicebus_alloc(vb);
  54. if (!vbb)
  55. return NULL;
  56. res = skb_copy_bits(skb, COMMON_HEADER, vbb, VOICEBUS_SFRAME_SIZE);
  57. if (res) {
  58. dev_warn(&vb->pdev->dev, "Failed call to skb_copy_bits.\n");
  59. voicebus_free(vb, vbb);
  60. return NULL;
  61. }
  62. return vbb;
  63. }
  64. static int
  65. vb_net_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)
  66. {
  67. struct voicebus *vb = voicebus_from_netdev(netdev);
  68. void *vbb;
  69. vbb = skb_to_vbb(vb, skb);
  70. if (vbb)
  71. voicebus_transmit(vb, vbb);
  72. dev_kfree_skb_any(skb);
  73. return NETDEV_TX_OK;
  74. }
  75. static int vb_net_receive(struct voicebus *vb, int max)
  76. {
  77. int count = 0;
  78. struct sk_buff *skb;
  79. WARN_ON(0 == max);
  80. while ((skb = skb_dequeue(&vb->captured_packets))) {
  81. netif_receive_skb(skb);
  82. if (++count >= max)
  83. break;
  84. }
  85. return count;
  86. }
  87. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
  88. static int vb_net_poll(struct net_device *netdev, int *budget)
  89. {
  90. struct voicebus *vb = voicebus_from_netdev(netdev);
  91. int count = 0;
  92. int quota = min(netdev->quota, *budget);
  93. count = vb_net_receive(vb, quota);
  94. *budget -= count;
  95. netdev->quota -= count;
  96. if (!skb_queue_len(&vb->captured_packets)) {
  97. netif_rx_complete(netdev);
  98. return 0;
  99. } else {
  100. return -1;
  101. }
  102. }
  103. #else
  104. static int vb_net_poll(struct napi_struct *napi, int budget)
  105. {
  106. struct voicebus *vb = container_of(napi, struct voicebus, napi);
  107. int count;
  108. count = vb_net_receive(vb, budget);
  109. if (!skb_queue_len(&vb->captured_packets)) {
  110. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
  111. netif_rx_complete(vb->netdev, &vb->napi);
  112. #elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
  113. netif_rx_complete(&vb->napi);
  114. #else
  115. napi_complete(&vb->napi);
  116. #endif
  117. }
  118. return count;
  119. }
  120. #endif
  121. static void vb_net_set_multi(struct net_device *netdev)
  122. {
  123. struct voicebus *vb = voicebus_from_netdev(netdev);
  124. dev_dbg(&vb->pdev->dev, "%s promiscuity:%d\n",
  125. __func__, netdev->promiscuity);
  126. }
  127. static int vb_net_up(struct net_device *netdev)
  128. {
  129. struct voicebus *vb = voicebus_from_netdev(netdev);
  130. dev_dbg(&vb->pdev->dev, "%s\n", __func__);
  131. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
  132. netif_poll_enable(netdev);
  133. #else
  134. napi_enable(&vb->napi);
  135. #endif
  136. return 0;
  137. }
  138. static int vb_net_down(struct net_device *netdev)
  139. {
  140. struct voicebus *vb = voicebus_from_netdev(netdev);
  141. dev_dbg(&vb->pdev->dev, "%s\n", __func__);
  142. #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
  143. netif_poll_disable(netdev);
  144. #else
  145. napi_disable(&vb->napi);
  146. #endif
  147. return 0;
  148. }
  149. static struct net_device_stats *
  150. vb_net_get_stats(struct net_device *netdev)
  151. {
  152. struct voicebus *vb = voicebus_from_netdev(netdev);
  153. return &vb->net_stats;
  154. }
  155. #ifdef HAVE_NET_DEVICE_OPS
  156. static const struct net_device_ops vb_netdev_ops = {
  157. .ndo_set_multicast_list = &vb_net_set_multi,
  158. .ndo_open = &vb_net_up,
  159. .ndo_stop = &vb_net_down,
  160. .ndo_start_xmit = &vb_net_hard_start_xmit,
  161. .ndo_get_stats = &vb_net_get_stats,
  162. };
  163. #endif
  164. /**
  165. * vb_net_register - Register a new network interface.
  166. * @vb: voicebus card to register the interface for.
  167. *
  168. * The network interface is primarily used for debugging in order to watch the
  169. * traffic between the transcoder and the host.
  170. *
  171. */
  172. int vb_net_register(struct voicebus *vb, const char *board_name)
  173. {
  174. int res;
  175. struct net_device *netdev;
  176. struct voicebus_netdev_priv *priv;
  177. const char our_mac[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
  178. netdev = alloc_netdev(sizeof(*priv), board_name, ether_setup);
  179. if (!netdev)
  180. return -ENOMEM;
  181. priv = netdev_priv(netdev);
  182. priv->vb = vb;
  183. memcpy(netdev->dev_addr, our_mac, sizeof(our_mac));
  184. # ifdef HAVE_NET_DEVICE_OPS
  185. netdev->netdev_ops = &vb_netdev_ops;
  186. # else
  187. netdev->set_multicast_list = vb_net_set_multi;
  188. netdev->open = vb_net_up;
  189. netdev->stop = vb_net_down;
  190. netdev->hard_start_xmit = vb_net_hard_start_xmit;
  191. netdev->get_stats = vb_net_get_stats;
  192. # endif
  193. netdev->promiscuity = 0;
  194. netdev->flags |= IFF_NOARP;
  195. # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
  196. netdev->poll = vb_net_poll;
  197. netdev->weight = 64;
  198. # else
  199. netif_napi_add(netdev, &vb->napi, vb_net_poll, 64);
  200. # endif
  201. skb_queue_head_init(&vb->captured_packets);
  202. res = register_netdev(netdev);
  203. if (res) {
  204. dev_warn(&vb->pdev->dev,
  205. "Failed to register network device %s.\n", board_name);
  206. goto error_sw;
  207. }
  208. vb->netdev = netdev;
  209. dev_dbg(&vb->pdev->dev,
  210. "Created network device %s for debug.\n", board_name);
  211. return 0;
  212. error_sw:
  213. if (netdev)
  214. free_netdev(netdev);
  215. return res;
  216. }
  217. void vb_net_unregister(struct voicebus *wc)
  218. {
  219. struct sk_buff *skb;
  220. if (!wc->netdev)
  221. return;
  222. unregister_netdev(wc->netdev);
  223. while ((skb = skb_dequeue(&wc->captured_packets)))
  224. kfree_skb(skb);
  225. free_netdev(wc->netdev);
  226. wc->netdev = NULL;
  227. }
  228. /* Header format for the voicebus network interface. */
  229. struct voicebus_net_hdr {
  230. struct ethhdr ethhdr;
  231. __be16 seq_num;
  232. __be32 des0;
  233. __be16 tag;
  234. __be16 filler[4];
  235. } __attribute__((packed));
  236. static struct sk_buff *
  237. vbb_to_skb(struct net_device *netdev, const void *vbb, const int tx,
  238. const u32 des0, const u16 tag)
  239. {
  240. struct voicebus *vb = voicebus_from_netdev(netdev);
  241. struct sk_buff *skb;
  242. struct voicebus_net_hdr *hdr;
  243. /* 0x88B5 is the local experimental ethertype */
  244. const u16 VOICEBUS_ETHTYPE = 0x88b5;
  245. const u8 BOARD_MAC[6] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11};
  246. const u8 HOST_MAC[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  247. skb = netdev_alloc_skb(vb->netdev,
  248. VOICEBUS_SFRAME_SIZE + sizeof(*hdr) + NET_IP_ALIGN);
  249. if (!skb)
  250. return NULL;
  251. skb_reserve(skb, NET_IP_ALIGN);
  252. skb->dev = netdev;
  253. hdr = (struct voicebus_net_hdr *)skb_put(skb, VOICEBUS_SFRAME_SIZE +
  254. sizeof(*hdr));
  255. /* Fill in the source and destination mac addresses appropriately
  256. * depending on whether this is a packet we are transmitting or a packet
  257. * that we have received. */
  258. if (tx) {
  259. memcpy(hdr->ethhdr.h_dest, BOARD_MAC, sizeof(BOARD_MAC));
  260. memcpy(hdr->ethhdr.h_source, HOST_MAC, sizeof(HOST_MAC));
  261. hdr->seq_num = cpu_to_be16(atomic_inc_return(
  262. &vb->tx_seqnum));
  263. } else {
  264. memcpy(hdr->ethhdr.h_dest, HOST_MAC, sizeof(HOST_MAC));
  265. memcpy(hdr->ethhdr.h_source, BOARD_MAC, sizeof(BOARD_MAC));
  266. hdr->seq_num = cpu_to_be16(atomic_inc_return(
  267. &vb->rx_seqnum));
  268. }
  269. memset(hdr->filler, 0, sizeof(hdr->filler));
  270. hdr->des0 = cpu_to_be32(des0);
  271. hdr->tag = cpu_to_be16(tag);
  272. hdr->ethhdr.h_proto = htons(VOICEBUS_ETHTYPE);
  273. /* copy the rest of the packet. */
  274. memcpy(skb->data + sizeof(*hdr), vbb, VOICEBUS_SFRAME_SIZE);
  275. skb->protocol = eth_type_trans(skb, netdev);
  276. return skb;
  277. }
  278. /**
  279. * vb_net_capture_cmd - Send a vbb to the network stack.
  280. * @vb: Interface card received the command.
  281. * @vbb: Voicebus buffer to pass up..
  282. * @tx: 1 if this is a vbb that the driver is sending to the card.
  283. *
  284. */
  285. void vb_net_capture_vbb(struct voicebus *vb, const void *vbb, const int tx,
  286. const u32 des0, const u16 tag)
  287. {
  288. struct sk_buff *skb;
  289. struct net_device *netdev = vb->netdev;
  290. const int MAX_CAPTURED_PACKETS = 5000;
  291. if (!netdev)
  292. return;
  293. /* If the interface isn't up, we don't need to capture the packet. */
  294. if (!(netdev->flags & IFF_UP))
  295. return;
  296. if (skb_queue_len(&vb->captured_packets) > MAX_CAPTURED_PACKETS) {
  297. WARN_ON_ONCE(1);
  298. return;
  299. }
  300. skb = vbb_to_skb(netdev, vbb, tx, des0, tag);
  301. if (!skb)
  302. return;
  303. skb_queue_tail(&vb->captured_packets, skb);
  304. # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24)
  305. netif_rx_schedule(netdev);
  306. # elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
  307. netif_rx_schedule(netdev, &vb->napi);
  308. # elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 30)
  309. netif_rx_schedule(&vb->napi);
  310. # else
  311. napi_schedule(&vb->napi);
  312. # endif
  313. return;
  314. }
  315. #endif