qca_uart.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. /*
  2. * Copyright (c) 2011, 2012, Qualcomm Atheros Communications Inc.
  3. * Copyright (c) 2017, I2SE GmbH
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software
  6. * for any purpose with or without fee is hereby granted, provided
  7. * that the above copyright notice and this permission notice appear
  8. * in all copies.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  11. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  12. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
  13. * THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
  14. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  15. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
  16. * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  17. * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. /* This module implements the Qualcomm Atheros UART protocol for
  20. * kernel-based UART device; it is essentially an Ethernet-to-UART
  21. * serial converter;
  22. */
  23. #include <linux/device.h>
  24. #include <linux/errno.h>
  25. #include <linux/etherdevice.h>
  26. #include <linux/if_arp.h>
  27. #include <linux/if_ether.h>
  28. #include <linux/jiffies.h>
  29. #include <linux/kernel.h>
  30. #include <linux/module.h>
  31. #include <linux/netdevice.h>
  32. #include <linux/of.h>
  33. #include <linux/of_device.h>
  34. #include <linux/of_net.h>
  35. #include <linux/sched.h>
  36. #include <linux/serdev.h>
  37. #include <linux/skbuff.h>
  38. #include <linux/types.h>
  39. #include "qca_7k_common.h"
  40. #define QCAUART_DRV_VERSION "0.1.0"
  41. #define QCAUART_DRV_NAME "qcauart"
  42. #define QCAUART_TX_TIMEOUT (1 * HZ)
  43. struct qcauart {
  44. struct net_device *net_dev;
  45. spinlock_t lock; /* transmit lock */
  46. struct work_struct tx_work; /* Flushes transmit buffer */
  47. struct serdev_device *serdev;
  48. struct qcafrm_handle frm_handle;
  49. struct sk_buff *rx_skb;
  50. unsigned char *tx_head; /* pointer to next XMIT byte */
  51. int tx_left; /* bytes left in XMIT queue */
  52. unsigned char *tx_buffer;
  53. };
  54. static int
  55. qca_tty_receive(struct serdev_device *serdev, const unsigned char *data,
  56. size_t count)
  57. {
  58. struct qcauart *qca = serdev_device_get_drvdata(serdev);
  59. struct net_device *netdev = qca->net_dev;
  60. struct net_device_stats *n_stats = &netdev->stats;
  61. size_t i;
  62. if (!qca->rx_skb) {
  63. qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
  64. netdev->mtu +
  65. VLAN_ETH_HLEN);
  66. if (!qca->rx_skb) {
  67. n_stats->rx_errors++;
  68. n_stats->rx_dropped++;
  69. return 0;
  70. }
  71. }
  72. for (i = 0; i < count; i++) {
  73. s32 retcode;
  74. retcode = qcafrm_fsm_decode(&qca->frm_handle,
  75. qca->rx_skb->data,
  76. skb_tailroom(qca->rx_skb),
  77. data[i]);
  78. switch (retcode) {
  79. case QCAFRM_GATHER:
  80. case QCAFRM_NOHEAD:
  81. break;
  82. case QCAFRM_NOTAIL:
  83. netdev_dbg(netdev, "recv: no RX tail\n");
  84. n_stats->rx_errors++;
  85. n_stats->rx_dropped++;
  86. break;
  87. case QCAFRM_INVLEN:
  88. netdev_dbg(netdev, "recv: invalid RX length\n");
  89. n_stats->rx_errors++;
  90. n_stats->rx_dropped++;
  91. break;
  92. default:
  93. n_stats->rx_packets++;
  94. n_stats->rx_bytes += retcode;
  95. skb_put(qca->rx_skb, retcode);
  96. qca->rx_skb->protocol = eth_type_trans(
  97. qca->rx_skb, qca->rx_skb->dev);
  98. qca->rx_skb->ip_summed = CHECKSUM_UNNECESSARY;
  99. netif_rx_ni(qca->rx_skb);
  100. qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
  101. netdev->mtu +
  102. VLAN_ETH_HLEN);
  103. if (!qca->rx_skb) {
  104. netdev_dbg(netdev, "recv: out of RX resources\n");
  105. n_stats->rx_errors++;
  106. return i;
  107. }
  108. }
  109. }
  110. return i;
  111. }
  112. /* Write out any remaining transmit buffer. Scheduled when tty is writable */
  113. static void qcauart_transmit(struct work_struct *work)
  114. {
  115. struct qcauart *qca = container_of(work, struct qcauart, tx_work);
  116. struct net_device_stats *n_stats = &qca->net_dev->stats;
  117. int written;
  118. spin_lock_bh(&qca->lock);
  119. /* First make sure we're connected. */
  120. if (!netif_running(qca->net_dev)) {
  121. spin_unlock_bh(&qca->lock);
  122. return;
  123. }
  124. if (qca->tx_left <= 0) {
  125. /* Now serial buffer is almost free & we can start
  126. * transmission of another packet
  127. */
  128. n_stats->tx_packets++;
  129. spin_unlock_bh(&qca->lock);
  130. netif_wake_queue(qca->net_dev);
  131. return;
  132. }
  133. written = serdev_device_write_buf(qca->serdev, qca->tx_head,
  134. qca->tx_left);
  135. if (written > 0) {
  136. qca->tx_left -= written;
  137. qca->tx_head += written;
  138. }
  139. spin_unlock_bh(&qca->lock);
  140. }
  141. /* Called by the driver when there's room for more data.
  142. * Schedule the transmit.
  143. */
  144. static void qca_tty_wakeup(struct serdev_device *serdev)
  145. {
  146. struct qcauart *qca = serdev_device_get_drvdata(serdev);
  147. schedule_work(&qca->tx_work);
  148. }
  149. static struct serdev_device_ops qca_serdev_ops = {
  150. .receive_buf = qca_tty_receive,
  151. .write_wakeup = qca_tty_wakeup,
  152. };
  153. static int qcauart_netdev_open(struct net_device *dev)
  154. {
  155. struct qcauart *qca = netdev_priv(dev);
  156. netif_start_queue(qca->net_dev);
  157. return 0;
  158. }
  159. static int qcauart_netdev_close(struct net_device *dev)
  160. {
  161. struct qcauart *qca = netdev_priv(dev);
  162. netif_stop_queue(dev);
  163. flush_work(&qca->tx_work);
  164. spin_lock_bh(&qca->lock);
  165. qca->tx_left = 0;
  166. spin_unlock_bh(&qca->lock);
  167. return 0;
  168. }
  169. static netdev_tx_t
  170. qcauart_netdev_xmit(struct sk_buff *skb, struct net_device *dev)
  171. {
  172. struct net_device_stats *n_stats = &dev->stats;
  173. struct qcauart *qca = netdev_priv(dev);
  174. u8 pad_len = 0;
  175. int written;
  176. u8 *pos;
  177. spin_lock(&qca->lock);
  178. WARN_ON(qca->tx_left);
  179. if (!netif_running(dev)) {
  180. spin_unlock(&qca->lock);
  181. netdev_warn(qca->net_dev, "xmit: iface is down\n");
  182. goto out;
  183. }
  184. pos = qca->tx_buffer;
  185. if (skb->len < QCAFRM_MIN_LEN)
  186. pad_len = QCAFRM_MIN_LEN - skb->len;
  187. pos += qcafrm_create_header(pos, skb->len + pad_len);
  188. memcpy(pos, skb->data, skb->len);
  189. pos += skb->len;
  190. if (pad_len) {
  191. memset(pos, 0, pad_len);
  192. pos += pad_len;
  193. }
  194. pos += qcafrm_create_footer(pos);
  195. netif_stop_queue(qca->net_dev);
  196. written = serdev_device_write_buf(qca->serdev, qca->tx_buffer,
  197. pos - qca->tx_buffer);
  198. if (written > 0) {
  199. qca->tx_left = (pos - qca->tx_buffer) - written;
  200. qca->tx_head = qca->tx_buffer + written;
  201. n_stats->tx_bytes += written;
  202. }
  203. spin_unlock(&qca->lock);
  204. netif_trans_update(dev);
  205. out:
  206. dev_kfree_skb_any(skb);
  207. return NETDEV_TX_OK;
  208. }
  209. static void qcauart_netdev_tx_timeout(struct net_device *dev)
  210. {
  211. struct qcauart *qca = netdev_priv(dev);
  212. netdev_info(qca->net_dev, "Transmit timeout at %ld, latency %ld\n",
  213. jiffies, dev_trans_start(dev));
  214. dev->stats.tx_errors++;
  215. dev->stats.tx_dropped++;
  216. }
  217. static int qcauart_netdev_init(struct net_device *dev)
  218. {
  219. struct qcauart *qca = netdev_priv(dev);
  220. size_t len;
  221. /* Finish setting up the device info. */
  222. dev->mtu = QCAFRM_MAX_MTU;
  223. dev->type = ARPHRD_ETHER;
  224. len = QCAFRM_HEADER_LEN + QCAFRM_MAX_LEN + QCAFRM_FOOTER_LEN;
  225. qca->tx_buffer = devm_kmalloc(&qca->serdev->dev, len, GFP_KERNEL);
  226. if (!qca->tx_buffer)
  227. return -ENOMEM;
  228. qca->rx_skb = netdev_alloc_skb_ip_align(qca->net_dev,
  229. qca->net_dev->mtu +
  230. VLAN_ETH_HLEN);
  231. if (!qca->rx_skb)
  232. return -ENOBUFS;
  233. return 0;
  234. }
  235. static void qcauart_netdev_uninit(struct net_device *dev)
  236. {
  237. struct qcauart *qca = netdev_priv(dev);
  238. if (qca->rx_skb)
  239. dev_kfree_skb(qca->rx_skb);
  240. }
  241. static const struct net_device_ops qcauart_netdev_ops = {
  242. .ndo_init = qcauart_netdev_init,
  243. .ndo_uninit = qcauart_netdev_uninit,
  244. .ndo_open = qcauart_netdev_open,
  245. .ndo_stop = qcauart_netdev_close,
  246. .ndo_start_xmit = qcauart_netdev_xmit,
  247. .ndo_set_mac_address = eth_mac_addr,
  248. .ndo_tx_timeout = qcauart_netdev_tx_timeout,
  249. .ndo_validate_addr = eth_validate_addr,
  250. };
  251. static void qcauart_netdev_setup(struct net_device *dev)
  252. {
  253. dev->netdev_ops = &qcauart_netdev_ops;
  254. dev->watchdog_timeo = QCAUART_TX_TIMEOUT;
  255. dev->priv_flags &= ~IFF_TX_SKB_SHARING;
  256. dev->tx_queue_len = 100;
  257. /* MTU range: 46 - 1500 */
  258. dev->min_mtu = QCAFRM_MIN_MTU;
  259. dev->max_mtu = QCAFRM_MAX_MTU;
  260. }
  261. static const struct of_device_id qca_uart_of_match[] = {
  262. {
  263. .compatible = "qca,qca7000",
  264. },
  265. {}
  266. };
  267. MODULE_DEVICE_TABLE(of, qca_uart_of_match);
  268. static int qca_uart_probe(struct serdev_device *serdev)
  269. {
  270. struct net_device *qcauart_dev = alloc_etherdev(sizeof(struct qcauart));
  271. struct qcauart *qca;
  272. const char *mac;
  273. u32 speed = 115200;
  274. int ret;
  275. if (!qcauart_dev)
  276. return -ENOMEM;
  277. qcauart_netdev_setup(qcauart_dev);
  278. SET_NETDEV_DEV(qcauart_dev, &serdev->dev);
  279. qca = netdev_priv(qcauart_dev);
  280. if (!qca) {
  281. pr_err("qca_uart: Fail to retrieve private structure\n");
  282. ret = -ENOMEM;
  283. goto free;
  284. }
  285. qca->net_dev = qcauart_dev;
  286. qca->serdev = serdev;
  287. qcafrm_fsm_init_uart(&qca->frm_handle);
  288. spin_lock_init(&qca->lock);
  289. INIT_WORK(&qca->tx_work, qcauart_transmit);
  290. of_property_read_u32(serdev->dev.of_node, "current-speed", &speed);
  291. mac = of_get_mac_address(serdev->dev.of_node);
  292. if (mac)
  293. ether_addr_copy(qca->net_dev->dev_addr, mac);
  294. if (!is_valid_ether_addr(qca->net_dev->dev_addr)) {
  295. eth_hw_addr_random(qca->net_dev);
  296. dev_info(&serdev->dev, "Using random MAC address: %pM\n",
  297. qca->net_dev->dev_addr);
  298. }
  299. netif_carrier_on(qca->net_dev);
  300. serdev_device_set_drvdata(serdev, qca);
  301. serdev_device_set_client_ops(serdev, &qca_serdev_ops);
  302. ret = serdev_device_open(serdev);
  303. if (ret) {
  304. dev_err(&serdev->dev, "Unable to open device %s\n",
  305. qcauart_dev->name);
  306. goto free;
  307. }
  308. speed = serdev_device_set_baudrate(serdev, speed);
  309. dev_info(&serdev->dev, "Using baudrate: %u\n", speed);
  310. serdev_device_set_flow_control(serdev, false);
  311. ret = register_netdev(qcauart_dev);
  312. if (ret) {
  313. dev_err(&serdev->dev, "Unable to register net device %s\n",
  314. qcauart_dev->name);
  315. serdev_device_close(serdev);
  316. cancel_work_sync(&qca->tx_work);
  317. goto free;
  318. }
  319. return 0;
  320. free:
  321. free_netdev(qcauart_dev);
  322. return ret;
  323. }
  324. static void qca_uart_remove(struct serdev_device *serdev)
  325. {
  326. struct qcauart *qca = serdev_device_get_drvdata(serdev);
  327. unregister_netdev(qca->net_dev);
  328. /* Flush any pending characters in the driver. */
  329. serdev_device_close(serdev);
  330. cancel_work_sync(&qca->tx_work);
  331. free_netdev(qca->net_dev);
  332. }
  333. static struct serdev_device_driver qca_uart_driver = {
  334. .probe = qca_uart_probe,
  335. .remove = qca_uart_remove,
  336. .driver = {
  337. .name = QCAUART_DRV_NAME,
  338. .of_match_table = of_match_ptr(qca_uart_of_match),
  339. },
  340. };
  341. module_serdev_device_driver(qca_uart_driver);
  342. MODULE_DESCRIPTION("Qualcomm Atheros QCA7000 UART Driver");
  343. MODULE_AUTHOR("Qualcomm Atheros Communications");
  344. MODULE_AUTHOR("Stefan Wahren <stefan.wahren@i2se.com>");
  345. MODULE_LICENSE("Dual BSD/GPL");
  346. MODULE_VERSION(QCAUART_DRV_VERSION);