Linux/m68k driver for MNT ZZ9000
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

342 lines
8.0 KiB

  1. /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
  2. #include <linux/console.h>
  3. #include <linux/netdevice.h>
  4. #include <linux/etherdevice.h>
  5. #include <linux/module.h>
  6. #include <linux/zorro.h>
  7. #include <asm/amigahw.h>
  8. #include <asm/amigaints.h>
  9. #include "zz9000.h"
  10. static struct zz9000_platform_data *zz9000_data;
  11. /* Length definitions */
  12. static unsigned char zz9000_mac_addr[ETH_ALEN];
  13. /* net_device referencing */
  14. static struct net_device *device;
  15. static struct net_device_stats *stats;
  16. /* priv structure that holds the informations about the device. */
  17. struct eth_priv {
  18. spinlock_t lock;
  19. struct net_device *dev;
  20. };
  21. static void zz9000_hw_tx(char *data, int len, struct net_device *dev)
  22. {
  23. void *zz9000_tx_mem = zz9000_data->eth_tx_mem;
  24. uint16_t ret;
  25. memcpy(zz9000_tx_mem, data, len);
  26. #if 0
  27. netdev_dbg(dev, "send data=%p len=%d\n", data, len);
  28. print_hex_dump_debug("eth: ", DUMP_PREFIX_OFFSET,
  29. 16, 1, data, len, true);
  30. #endif
  31. zz_writew(len, MNTZZ_ETH_TX);
  32. ret = zz_readw(MNTZZ_ETH_TX);
  33. if (ret != 0)
  34. netdev_dbg(dev, "ret = %d\n", ret);
  35. }
  36. static uint32_t old_serial = 0;
  37. /*
  38. * Read a packet out of the adapter and pass it to the upper layers
  39. */
  40. static inline int recv_packet(struct net_device *dev)
  41. {
  42. unsigned short pktlen;
  43. struct sk_buff *skb;
  44. uint8_t *frame = (uint8_t *) zz9000_data->eth_rx_mem;
  45. uint32_t ser = ((uint32_t) frame[2] << 8) | ((uint32_t) frame[3]);
  46. pktlen = ((uint32_t) frame[0] << 8) | ((uint32_t) frame[1]);
  47. /* There is not interrupt status register for network,
  48. * so we use the serial number of the frame to determine
  49. * whether there's a new packet
  50. */
  51. if (old_serial == ser)
  52. return 0;
  53. old_serial = ser;
  54. if (!pktlen) {
  55. netdev_dbg(dev, "%s: pktlen == 0\n", __func__);
  56. dev->stats.rx_errors++;
  57. return -1;
  58. }
  59. skb = dev_alloc_skb(pktlen + 2);
  60. if (!skb) {
  61. netdev_dbg(dev, "%s: out of mem (buf_alloc failed)\n",
  62. __func__);
  63. dev->stats.rx_dropped++;
  64. return -1;
  65. }
  66. skb->dev = dev;
  67. #if 0
  68. skb_reserve(skb, NET_IP_ALIGN);
  69. skb_put(skb, pktlen); /* make room */
  70. //print_hex_dump_debug("eth: ", DUMP_PREFIX_OFFSET,
  71. // 16, 1, frame, pktlen, true);
  72. // Copy buffer to skb
  73. memcpy(skb->data, frame + 4, pktlen);
  74. #else
  75. memcpy(skb_put(skb, pktlen), frame + 4, pktlen);
  76. #endif
  77. /* Mark this frame as accepted */
  78. zz_writew(0x0001, MNTZZ_ETH_RX);
  79. skb->protocol = eth_type_trans(skb, dev);
  80. skb->ip_summed = CHECKSUM_NONE;
  81. dev->stats.rx_packets++;
  82. dev->stats.rx_bytes += pktlen;
  83. netif_rx(skb);
  84. /* and enqueue packet */
  85. return 1;
  86. }
  87. static irqreturn_t zz9000_eth_interrupt(int irq, void *dev_id)
  88. {
  89. struct eth_priv *priv;
  90. int rcv = 1;
  91. struct net_device *dev = (struct net_device *)dev_id;
  92. /* paranoid */
  93. if (!dev)
  94. return IRQ_HANDLED;
  95. /* Lock the device */
  96. priv = netdev_priv(dev);
  97. spin_lock(&priv->lock);
  98. /* Fetch all available packets. */
  99. while (rcv) {
  100. rcv = recv_packet(dev);
  101. }
  102. /* Unlock the device and we are done */
  103. spin_unlock(&priv->lock);
  104. return IRQ_HANDLED;
  105. }
  106. static int zz9000_eth_open(struct net_device *dev)
  107. {
  108. int ret;
  109. /* Install interrupt handler for IRQ6.
  110. * IRQ2 is currently not supported.
  111. */
  112. ret = request_irq(IRQ_AMIGA_EXTER, zz9000_eth_interrupt, IRQF_SHARED,
  113. "ZZ9000 Ethernet", dev);
  114. if (ret)
  115. return ret;
  116. /* Enable Interrupts on ZZ9000 */
  117. zz_writew(zz_readw(MNTZZ_CONFIG) | 0x01, MNTZZ_CONFIG);
  118. /* start up the transmission queue */
  119. netif_start_queue(dev);
  120. return 0;
  121. }
  122. static int zz9000_eth_close(struct net_device *dev)
  123. {
  124. /* Disable interrupts on ZZ9000 */
  125. zz_writew(zz_readw(MNTZZ_CONFIG) & 0xfffe, MNTZZ_CONFIG);
  126. /* shutdown the transmission queue */
  127. netif_stop_queue(dev);
  128. /* Remove interrupt handler */
  129. free_irq(IRQ_AMIGA_EXTER, dev);
  130. return 0;
  131. }
  132. static int zz9000_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
  133. {
  134. int len;
  135. char *data, shortpkt[ETH_ZLEN];
  136. data = skb->data;
  137. len = skb->len;
  138. if (len < ETH_ZLEN) {
  139. memset(shortpkt, 0, ETH_ZLEN);
  140. memcpy(shortpkt, skb->data, skb->len);
  141. len = ETH_ZLEN;
  142. data = shortpkt;
  143. }
  144. /* Send that packet out! */
  145. zz9000_hw_tx(data, len, dev);
  146. dev->stats.tx_packets++;
  147. dev->stats.tx_bytes += len;
  148. dev_kfree_skb(skb);
  149. return NETDEV_TX_OK;
  150. }
  151. static int zz9000_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr,
  152. int cmd)
  153. {
  154. printk(KERN_INFO "zz9000_eth_do_ioctl(%s): 0x%x\n", dev->name, cmd);
  155. return -1;
  156. }
  157. static struct net_device_stats *zz9000_eth_get_stats(struct net_device *dev)
  158. {
  159. // printk(KERN_INFO "zz9000_eth_get_stats(%s)\n", dev->name);
  160. return stats;
  161. }
  162. /*
  163. * This is where ifconfig comes down and tells us who we are, etc.
  164. * We can just ignore this.
  165. */
  166. static int zz9000_eth_config(struct net_device *dev, struct ifmap *map)
  167. {
  168. printk("zz9000_eth_config(%s)\n", dev->name);
  169. if (dev->flags & IFF_UP) {
  170. return -EBUSY;
  171. }
  172. return 0;
  173. }
  174. static int zz9000_eth_change_mtu(struct net_device *dev, int new_mtu)
  175. {
  176. unsigned long flags = 0;
  177. struct eth_priv *priv = netdev_priv(dev);
  178. spinlock_t *lock = &priv->lock;
  179. printk(KERN_INFO "zz9000_eth_change_mtu(%s)\n", dev->name);
  180. /* Check ranges */
  181. if ((new_mtu < 68) || (new_mtu > 10000)) // Remember to see at the hardware documentation the right especification
  182. return -EINVAL;
  183. spin_unlock_irqrestore(lock, flags);
  184. printk(KERN_INFO "Old mtu: (%d) New mtu: (%d)", dev->mtu, new_mtu);
  185. dev->mtu = new_mtu;
  186. spin_unlock_irqrestore(lock, flags);
  187. return 0; /* Sucess */
  188. }
  189. static void zz9000_eth_tx_timeout(struct net_device *dev, unsigned int tx_queue)
  190. {
  191. dev->stats.tx_errors++;
  192. netif_wake_queue(dev);
  193. return;
  194. }
  195. /*
  196. * Structure that holds all the options supported by the driver.
  197. */
  198. static struct net_device_ops zz9000_netdev_ops = {
  199. .ndo_open = zz9000_eth_open,
  200. .ndo_stop = zz9000_eth_close,
  201. .ndo_start_xmit = zz9000_eth_start_xmit,
  202. .ndo_do_ioctl = zz9000_eth_do_ioctl,
  203. .ndo_get_stats = zz9000_eth_get_stats,
  204. .ndo_set_config = zz9000_eth_config,
  205. .ndo_change_mtu = zz9000_eth_change_mtu,
  206. .ndo_tx_timeout = zz9000_eth_tx_timeout,
  207. // Does NAPI even make sense for this device?
  208. //.ndo_poll_controller = zz9000_eth_napi_poll;
  209. };
  210. static void zz9000_eth_setup(struct net_device *dev)
  211. {
  212. zz9000_mac_addr[0] = zz_readw(MNTZZ_ETH_MAC_HI) >> 8;
  213. zz9000_mac_addr[1] = zz_readw(MNTZZ_ETH_MAC_HI) & 0xff;
  214. zz9000_mac_addr[2] = zz_readw(MNTZZ_ETH_MAC_MD) >> 8;
  215. zz9000_mac_addr[3] = zz_readw(MNTZZ_ETH_MAC_MD) & 0xff;
  216. zz9000_mac_addr[4] = zz_readw(MNTZZ_ETH_MAC_LO) >> 8;
  217. zz9000_mac_addr[5] = zz_readw(MNTZZ_ETH_MAC_LO) & 0xff;
  218. ether_setup(dev);
  219. dev->netdev_ops = &zz9000_netdev_ops;
  220. dev->irq = IRQ_AMIGA_EXTER;
  221. dev->hard_header_len = ETH_HLEN;
  222. dev->mtu = ETH_DATA_LEN;
  223. dev->addr_len = ETH_ALEN;
  224. dev->flags |= IFF_BROADCAST | IFF_MULTICAST;
  225. memset(dev->broadcast, 0xFF, ETH_ALEN);
  226. memcpy(dev->dev_addr, zz9000_mac_addr, ETH_ALEN);
  227. stats = &dev->stats;
  228. }
  229. int zz9000_network_init(struct zz9000_platform_data *data)
  230. {
  231. int ret = 0;
  232. zz9000_data = data;
  233. /* Allocating the net device. */
  234. device = alloc_netdev(0, "eth%d", NET_NAME_UNKNOWN, zz9000_eth_setup);
  235. if ((ret = register_netdev(device))) {
  236. printk(KERN_EMERG
  237. "zz9000: net: error %i registering device \"%s\"\n", ret,
  238. device->name);
  239. free_netdev(device);
  240. return -1;
  241. }
  242. printk(KERN_INFO " ZZ9000 Ethernet %s MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
  243. dev_name(&device->dev),
  244. zz9000_mac_addr[0], zz9000_mac_addr[1], zz9000_mac_addr[2],
  245. zz9000_mac_addr[3], zz9000_mac_addr[4], zz9000_mac_addr[5]);
  246. return 0;
  247. }
  248. int zz9000_network_remove(struct zz9000_platform_data *data)
  249. {
  250. if (device) {
  251. unregister_netdev(device);
  252. free_netdev(device);
  253. printk(KERN_INFO "zz9000: Network device removed.\n");
  254. }
  255. return 0;
  256. }
  257. static int __init zz9000_network_module_init(void)
  258. {
  259. struct zz9000_platform_data *data = get_zz9000_data();
  260. return zz9000_network_init(data);
  261. }
  262. module_init(zz9000_network_module_init);
  263. static void __exit zz9000_network_module_exit(void)
  264. {
  265. struct zz9000_platform_data *data = get_zz9000_data();
  266. zz9000_network_remove(data);
  267. }
  268. module_exit(zz9000_network_module_exit);
  269. MODULE_DESCRIPTION("MNT ZZ9000 network driver");
  270. MODULE_AUTHOR("Stefan Reinauer <stefan.reinauer@coreboot.org>");
  271. MODULE_LICENSE("GPL");