^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* FDDI network adapter driver for DEC FDDIcontroller 700/700-C devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) 2018 Maciej W. Rozycki
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This program is free software; you can redistribute it and/or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * modify it under the terms of the GNU General Public License
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * as published by the Free Software Foundation; either version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * 2 of the License, or (at your option) any later version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * References:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Dave Sawyer & Phil Weeks & Frank Itkowsky,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * "DEC FDDIcontroller 700 Port Specification",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Revision 1.1, Digital Equipment Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) /* FZA configurable parameters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) /* The number of transmit ring descriptors; either 0 for 512 or 1 for 1024. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define FZA_RING_TX_MODE 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* The number of receive ring descriptors; from 2 up to 256. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define FZA_RING_RX_SIZE 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* End of FZA configurable parameters. No need to change anything below. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /* ------------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/io-64-nonatomic-lo-hi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/fddidevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/tc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include <asm/barrier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include "defza.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define DRV_NAME "defza"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define DRV_VERSION "v.1.1.4"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define DRV_RELDATE "Oct 6 2018"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static const char version[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) DRV_NAME ": " DRV_VERSION " " DRV_RELDATE " Maciej W. Rozycki\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) MODULE_AUTHOR("Maciej W. Rozycki <macro@linux-mips.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) MODULE_DESCRIPTION("DEC FDDIcontroller 700 (DEFZA-xx) driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int loopback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) module_param(loopback, int, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* Ring Purger Multicast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) static u8 hw_addr_purger[8] = { 0x09, 0x00, 0x2b, 0x02, 0x01, 0x05 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) /* Directed Beacon Multicast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static u8 hw_addr_beacon[8] = { 0x01, 0x80, 0xc2, 0x00, 0x01, 0x00 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) /* Shorthands for MMIO accesses that we require to be strongly ordered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * WRT preceding MMIO accesses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define readw_o readw_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define readl_o readl_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define writew_o writew_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define writel_o writel_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /* Shorthands for MMIO accesses that we are happy with being weakly ordered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * WRT preceding MMIO accesses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define readw_u readw_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define readl_u readl_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define readq_u readq_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define writew_u writew_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define writel_u writel_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define writeq_u writeq_relaxed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) static inline struct sk_buff *fza_alloc_skb_irq(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return __netdev_alloc_skb(dev, length, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static inline struct sk_buff *fza_alloc_skb(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) unsigned int length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return __netdev_alloc_skb(dev, length, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static inline void fza_skb_align(struct sk_buff *skb, unsigned int v)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) unsigned long x, y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) x = (unsigned long)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) y = ALIGN(x, v);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) skb_reserve(skb, y - x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static inline void fza_reads(const void __iomem *from, void *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (sizeof(unsigned long) == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) const u64 __iomem *src = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) const u32 __iomem *src_trail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) u64 *dst = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) u32 *dst_trail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) for (size = (size + 3) / 4; size > 1; size -= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) *dst++ = readq_u(src++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) src_trail = (u32 __iomem *)src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) dst_trail = (u32 *)dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) *dst_trail = readl_u(src_trail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) const u32 __iomem *src = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) u32 *dst = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) for (size = (size + 3) / 4; size; size--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) *dst++ = readl_u(src++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) static inline void fza_writes(const void *from, void __iomem *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if (sizeof(unsigned long) == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) const u64 *src = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) const u32 *src_trail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u64 __iomem *dst = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u32 __iomem *dst_trail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) for (size = (size + 3) / 4; size > 1; size -= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) writeq_u(*src++, dst++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) src_trail = (u32 *)src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) dst_trail = (u32 __iomem *)dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) writel_u(*src_trail, dst_trail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) const u32 *src = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u32 __iomem *dst = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) for (size = (size + 3) / 4; size; size--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) writel_u(*src++, dst++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static inline void fza_moves(const void __iomem *from, void __iomem *to,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (sizeof(unsigned long) == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) const u64 __iomem *src = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) const u32 __iomem *src_trail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u64 __iomem *dst = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u32 __iomem *dst_trail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) for (size = (size + 3) / 4; size > 1; size -= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) writeq_u(readq_u(src++), dst++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) src_trail = (u32 __iomem *)src;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) dst_trail = (u32 __iomem *)dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) writel_u(readl_u(src_trail), dst_trail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) const u32 __iomem *src = from;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u32 __iomem *dst = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) for (size = (size + 3) / 4; size; size--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) writel_u(readl_u(src++), dst++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static inline void fza_zeros(void __iomem *to, unsigned long size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (sizeof(unsigned long) == 8) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u64 __iomem *dst = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u32 __iomem *dst_trail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) for (size = (size + 3) / 4; size > 1; size -= 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) writeq_u(0, dst++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) dst_trail = (u32 __iomem *)dst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) writel_u(0, dst_trail);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) u32 __iomem *dst = to;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) for (size = (size + 3) / 4; size; size--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) writel_u(0, dst++);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static inline void fza_regs_dump(struct fza_private *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pr_debug("%s: iomem registers:\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) pr_debug(" reset: 0x%04x\n", readw_o(&fp->regs->reset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) pr_debug(" interrupt event: 0x%04x\n", readw_u(&fp->regs->int_event));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) pr_debug(" status: 0x%04x\n", readw_u(&fp->regs->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) pr_debug(" interrupt mask: 0x%04x\n", readw_u(&fp->regs->int_mask));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) pr_debug(" control A: 0x%04x\n", readw_u(&fp->regs->control_a));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) pr_debug(" control B: 0x%04x\n", readw_u(&fp->regs->control_b));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static inline void fza_do_reset(struct fza_private *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) /* Reset the board. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) writew_o(FZA_RESET_INIT, &fp->regs->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) readw_o(&fp->regs->reset); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) readw_o(&fp->regs->reset); /* Read it back for a small delay. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) writew_o(FZA_RESET_CLR, &fp->regs->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* Enable all interrupt events we handle. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) writew_o(fp->int_mask, &fp->regs->int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) readw_o(&fp->regs->int_mask); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static inline void fza_do_shutdown(struct fza_private *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Disable the driver mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) writew_o(FZA_CONTROL_B_IDLE, &fp->regs->control_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) /* And reset the board. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) writew_o(FZA_RESET_INIT, &fp->regs->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) readw_o(&fp->regs->reset); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) writew_o(FZA_RESET_CLR, &fp->regs->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) readw_o(&fp->regs->reset); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) static int fza_reset(struct fza_private *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) uint status, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) pr_info("%s: resetting the board...\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) spin_lock_irqsave(&fp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) fp->state_chg_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) fza_do_reset(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) spin_unlock_irqrestore(&fp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* DEC says RESET needs up to 30 seconds to complete. My DEFZA-AA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * rev. C03 happily finishes in 9.7 seconds. :-) But we need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * be on the safe side...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) t = wait_event_timeout(fp->state_chg_wait, fp->state_chg_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 45 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) status = readw_u(&fp->regs->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) state = FZA_STATUS_GET_STATE(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (fp->state_chg_flag == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) pr_err("%s: RESET timed out!, state %x\n", fp->name, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (state != FZA_STATE_UNINITIALIZED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) pr_err("%s: RESET failed!, state %x, failure ID %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) fp->name, state, FZA_STATUS_GET_TEST(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) pr_info("%s: OK\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) pr_debug("%s: RESET: %lums elapsed\n", fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) (45 * HZ - t) * 1000 / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static struct fza_ring_cmd __iomem *fza_cmd_send(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int command)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) struct fza_ring_cmd __iomem *ring = fp->ring_cmd + fp->ring_cmd_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) unsigned int old_mask, new_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) union fza_cmd_buf __iomem *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) old_mask = fp->int_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) new_mask = old_mask & ~FZA_MASK_STATE_CHG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) writew_u(new_mask, &fp->regs->int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) readw_o(&fp->regs->int_mask); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) fp->int_mask = new_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) buf = fp->mmio + readl_u(&ring->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if ((readl_u(&ring->cmd_own) & FZA_RING_OWN_MASK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) FZA_RING_OWN_HOST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) pr_warn("%s: command buffer full, command: %u!\n", fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) command);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) switch (command) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) case FZA_RING_CMD_INIT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) writel_u(FZA_RING_TX_MODE, &buf->init.tx_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) writel_u(FZA_RING_RX_SIZE, &buf->init.hst_rx_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) fza_zeros(&buf->init.counters, sizeof(buf->init.counters));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case FZA_RING_CMD_MODCAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) i = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) fza_writes(&hw_addr_purger, &buf->cam.hw_addr[i++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) sizeof(*buf->cam.hw_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) fza_writes(&hw_addr_beacon, &buf->cam.hw_addr[i++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) sizeof(*buf->cam.hw_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) netdev_for_each_mc_addr(ha, dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (i >= FZA_CMD_CAM_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) fza_writes(ha->addr, &buf->cam.hw_addr[i++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) sizeof(*buf->cam.hw_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) while (i < FZA_CMD_CAM_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) fza_zeros(&buf->cam.hw_addr[i++],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) sizeof(*buf->cam.hw_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) case FZA_RING_CMD_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) writel_u(loopback, &buf->param.loop_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) writel_u(fp->t_max, &buf->param.t_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) writel_u(fp->t_req, &buf->param.t_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) writel_u(fp->tvx, &buf->param.tvx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) writel_u(fp->lem_threshold, &buf->param.lem_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) fza_writes(&fp->station_id, &buf->param.station_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) sizeof(buf->param.station_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) /* Convert to milliseconds due to buggy firmware. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) writel_u(fp->rtoken_timeout / 12500,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) &buf->param.rtoken_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) writel_u(fp->ring_purger, &buf->param.ring_purger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) case FZA_RING_CMD_MODPROM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (dev->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) writel_u(1, &buf->modprom.llc_prom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) writel_u(1, &buf->modprom.smt_prom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) writel_u(0, &buf->modprom.llc_prom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) writel_u(0, &buf->modprom.smt_prom);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (dev->flags & IFF_ALLMULTI ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) netdev_mc_count(dev) > FZA_CMD_CAM_SIZE - 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) writel_u(1, &buf->modprom.llc_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) writel_u(0, &buf->modprom.llc_multi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) writel_u(1, &buf->modprom.llc_bcast);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* Trigger the command. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) writel_u(FZA_RING_OWN_FZA | command, &ring->cmd_own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) writew_o(FZA_CONTROL_A_CMD_POLL, &fp->regs->control_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) fp->ring_cmd_index = (fp->ring_cmd_index + 1) % FZA_RING_CMD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) fp->int_mask = old_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) writew_u(fp->int_mask, &fp->regs->int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) static int fza_init_send(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct fza_cmd_init *__iomem *init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct fza_ring_cmd __iomem *ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) u32 stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) spin_lock_irqsave(&fp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) fp->cmd_done_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ring = fza_cmd_send(dev, FZA_RING_CMD_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) spin_unlock_irqrestore(&fp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) if (!ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* This should never happen in the uninitialized state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * so do not try to recover and just consider it fatal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* INIT may take quite a long time (160ms for my C03). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) t = wait_event_timeout(fp->cmd_done_wait, fp->cmd_done_flag, 3 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (fp->cmd_done_flag == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) pr_err("%s: INIT command timed out!, state %x\n", fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) FZA_STATUS_GET_STATE(readw_u(&fp->regs->status)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) stat = readl_u(&ring->stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (stat != FZA_RING_STAT_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) pr_err("%s: INIT command failed!, status %02x, state %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) fp->name, stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) FZA_STATUS_GET_STATE(readw_u(&fp->regs->status)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) pr_debug("%s: INIT: %lums elapsed\n", fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) (3 * HZ - t) * 1000 / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) *init = fp->mmio + readl_u(&ring->buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static void fza_rx_init(struct fza_private *fp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Fill the host receive descriptor ring. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) for (i = 0; i < FZA_RING_RX_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) writel_o(0, &fp->ring_hst_rx[i].rmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) writel_o((fp->rx_dma[i] + 0x1000) >> 9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) &fp->ring_hst_rx[i].buffer1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) writel_o(fp->rx_dma[i] >> 9 | FZA_RING_OWN_FZA,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) &fp->ring_hst_rx[i].buf0_own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) static void fza_set_rx_mode(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) fza_cmd_send(dev, FZA_RING_CMD_MODCAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) fza_cmd_send(dev, FZA_RING_CMD_MODPROM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) union fza_buffer_txp {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct fza_buffer_tx *data_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct fza_buffer_tx __iomem *mmio_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) static int fza_do_xmit(union fza_buffer_txp ub, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct net_device *dev, int smt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct fza_buffer_tx __iomem *rmc_tx_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) int i, first, frag_len, left_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) u32 own, rmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (((((fp->ring_rmc_txd_index - 1 + fp->ring_rmc_tx_size) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) fp->ring_rmc_tx_index) % fp->ring_rmc_tx_size) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) FZA_TX_BUFFER_SIZE) < len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) first = fp->ring_rmc_tx_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) left_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) frag_len = FZA_TX_BUFFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* First descriptor is relinquished last. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) own = FZA_RING_TX_OWN_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* First descriptor carries frame length; we don't use cut-through. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) rmc = FZA_RING_TX_SOP | FZA_RING_TX_VBC | len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) i = fp->ring_rmc_tx_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) rmc_tx_ptr = &fp->buffer_tx[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (left_len < FZA_TX_BUFFER_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) frag_len = left_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) left_len -= frag_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /* Length must be a multiple of 4 as only word writes are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * permitted!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) frag_len = (frag_len + 3) & ~3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) if (smt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) fza_moves(ub.mmio_ptr, rmc_tx_ptr, frag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) fza_writes(ub.data_ptr, rmc_tx_ptr, frag_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (left_len == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) rmc |= FZA_RING_TX_EOP; /* Mark last frag. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) writel_o(rmc, &fp->ring_rmc_tx[i].rmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) writel_o(own, &fp->ring_rmc_tx[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ub.data_ptr++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) fp->ring_rmc_tx_index = (fp->ring_rmc_tx_index + 1) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) fp->ring_rmc_tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Settings for intermediate frags. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) own = FZA_RING_TX_OWN_RMC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) rmc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) } while (left_len > 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (((((fp->ring_rmc_txd_index - 1 + fp->ring_rmc_tx_size) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) fp->ring_rmc_tx_index) % fp->ring_rmc_tx_size) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) FZA_TX_BUFFER_SIZE) < dev->mtu + dev->hard_header_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) pr_debug("%s: queue stopped\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) writel_o(FZA_RING_TX_OWN_RMC, &fp->ring_rmc_tx[first].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /* Go, go, go! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) writew_o(FZA_CONTROL_A_TX_POLL, &fp->regs->control_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) static int fza_do_recv_smt(struct fza_buffer_tx *data_ptr, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) u32 rmc, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct fza_buffer_tx __iomem *smt_rx_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) u32 own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) i = fp->ring_smt_rx_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) own = readl_o(&fp->ring_smt_rx[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if ((own & FZA_RING_OWN_MASK) == FZA_RING_OWN_FZA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) smt_rx_ptr = fp->mmio + readl_u(&fp->ring_smt_rx[i].buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) /* Length must be a multiple of 4 as only word writes are permitted! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) fza_writes(data_ptr, smt_rx_ptr, (len + 3) & ~3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) writel_o(rmc, &fp->ring_smt_rx[i].rmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) writel_o(FZA_RING_OWN_FZA, &fp->ring_smt_rx[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) fp->ring_smt_rx_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) (fp->ring_smt_rx_index + 1) % fp->ring_smt_rx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* Grab it! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) writew_o(FZA_CONTROL_A_SMT_RX_POLL, &fp->regs->control_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static void fza_tx(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) u32 own, rmc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) i = fp->ring_rmc_txd_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (i == fp->ring_rmc_tx_index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) own = readl_o(&fp->ring_rmc_tx[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if ((own & FZA_RING_OWN_MASK) == FZA_RING_TX_OWN_RMC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) rmc = readl_u(&fp->ring_rmc_tx[i].rmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* Only process the first descriptor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) if ((rmc & FZA_RING_TX_SOP) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if ((rmc & FZA_RING_TX_DCC_MASK) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) FZA_RING_TX_DCC_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) int pkt_len = (rmc & FZA_RING_PBC_MASK) - 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /* Omit PRH. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) fp->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) fp->stats.tx_bytes += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) fp->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) switch (rmc & FZA_RING_TX_DCC_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) case FZA_RING_TX_DCC_DTP_SOP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) case FZA_RING_TX_DCC_DTP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) case FZA_RING_TX_DCC_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) fp->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) case FZA_RING_TX_DCC_UNDRRUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) fp->stats.tx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) case FZA_RING_TX_DCC_PARITY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) fp->ring_rmc_txd_index = (fp->ring_rmc_txd_index + 1) %
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) fp->ring_rmc_tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) if (((((fp->ring_rmc_txd_index - 1 + fp->ring_rmc_tx_size) -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) fp->ring_rmc_tx_index) % fp->ring_rmc_tx_size) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) FZA_TX_BUFFER_SIZE) >= dev->mtu + dev->hard_header_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (fp->queue_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) pr_debug("%s: queue woken\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) static inline int fza_rx_err(struct fza_private *fp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) const u32 rmc, const u8 fc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) int len, min_len, max_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) len = rmc & FZA_RING_PBC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (unlikely((rmc & FZA_RING_RX_BAD) != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) fp->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* Check special status codes. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if ((rmc & (FZA_RING_RX_CRC | FZA_RING_RX_RRR_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) FZA_RING_RX_DA_MASK | FZA_RING_RX_SA_MASK)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) (FZA_RING_RX_CRC | FZA_RING_RX_RRR_DADDR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) FZA_RING_RX_DA_CAM | FZA_RING_RX_SA_ALIAS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) if (len >= 8190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) fp->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if ((rmc & (FZA_RING_RX_CRC | FZA_RING_RX_RRR_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) FZA_RING_RX_DA_MASK | FZA_RING_RX_SA_MASK)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) (FZA_RING_RX_CRC | FZA_RING_RX_RRR_DADDR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) FZA_RING_RX_DA_CAM | FZA_RING_RX_SA_CAM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) /* Halt the interface to trigger a reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) writew_o(FZA_CONTROL_A_HALT, &fp->regs->control_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) readw_o(&fp->regs->control_a); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* Check the MAC status. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) switch (rmc & FZA_RING_RX_RRR_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) case FZA_RING_RX_RRR_OK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) if ((rmc & FZA_RING_RX_CRC) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) fp->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) else if ((rmc & FZA_RING_RX_FSC_MASK) == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) (rmc & FZA_RING_RX_FSB_ERR) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) fp->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case FZA_RING_RX_RRR_SADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) case FZA_RING_RX_RRR_DADDR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) case FZA_RING_RX_RRR_ABORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) /* Halt the interface to trigger a reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) writew_o(FZA_CONTROL_A_HALT, &fp->regs->control_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) readw_o(&fp->regs->control_a); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) case FZA_RING_RX_RRR_LENGTH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) fp->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* Packet received successfully; validate the length. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) switch (fc & FDDI_FC_K_FORMAT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) case FDDI_FC_K_FORMAT_MANAGEMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) if ((fc & FDDI_FC_K_CLASS_MASK) == FDDI_FC_K_CLASS_ASYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) min_len = 37;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) min_len = 17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) case FDDI_FC_K_FORMAT_LLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) min_len = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) min_len = 17;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) max_len = 4495;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (len < min_len || len > max_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) fp->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) fp->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) static void fza_rx(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) struct sk_buff *skb, *newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct fza_fddihdr *frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) dma_addr_t dma, newdma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) u32 own, rmc, buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) u8 fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) i = fp->ring_hst_rx_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) own = readl_o(&fp->ring_hst_rx[i].buf0_own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if ((own & FZA_RING_OWN_MASK) == FZA_RING_OWN_FZA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) rmc = readl_u(&fp->ring_hst_rx[i].rmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) skb = fp->rx_skbuff[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) dma = fp->rx_dma[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /* The RMC doesn't count the preamble and the starting
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * delimiter. We fix it up here for a total of 3 octets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) dma_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) len = (rmc & FZA_RING_PBC_MASK) + 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) frame = (struct fza_fddihdr *)skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) /* We need to get at real FC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) dma_sync_single_for_cpu(fp->bdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dma +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) ((u8 *)&frame->hdr.fc - (u8 *)frame),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) sizeof(frame->hdr.fc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) fc = frame->hdr.fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (fza_rx_err(fp, rmc, fc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) goto err_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) /* We have to 512-byte-align RX buffers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) newskb = fza_alloc_skb_irq(dev, FZA_RX_BUFFER_SIZE + 511);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (newskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) fza_skb_align(newskb, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) newdma = dma_map_single(fp->bdev, newskb->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) FZA_RX_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (dma_mapping_error(fp->bdev, newdma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) dev_kfree_skb_irq(newskb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) newskb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (newskb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int pkt_len = len - 7; /* Omit P, SD and FCS. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) int is_multi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) int rx_stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) dma_unmap_single(fp->bdev, dma, FZA_RX_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) /* Queue SMT frames to the SMT receive ring. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) if ((fc & (FDDI_FC_K_CLASS_MASK |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) FDDI_FC_K_FORMAT_MASK)) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) (FDDI_FC_K_CLASS_ASYNC |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) FDDI_FC_K_FORMAT_MANAGEMENT) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) (rmc & FZA_RING_RX_DA_MASK) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) FZA_RING_RX_DA_PROM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) if (fza_do_recv_smt((struct fza_buffer_tx *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) skb->data, len, rmc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) writel_o(FZA_CONTROL_A_SMT_RX_OVFL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) &fp->regs->control_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) is_multi = ((frame->hdr.daddr[0] & 0x01) != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) skb_reserve(skb, 3); /* Skip over P and SD. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) skb_put(skb, pkt_len); /* And cut off FCS. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) skb->protocol = fddi_type_trans(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) rx_stat = netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (rx_stat != NET_RX_DROP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) fp->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) fp->stats.rx_bytes += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) if (is_multi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) fp->stats.multicast++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) fp->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) skb = newskb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) dma = newdma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) fp->rx_skbuff[i] = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) fp->rx_dma[i] = dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) fp->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) pr_notice("%s: memory squeeze, dropping packet\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) err_rx:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) writel_o(0, &fp->ring_hst_rx[i].rmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) buf = (dma + 0x1000) >> 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) writel_o(buf, &fp->ring_hst_rx[i].buffer1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) buf = dma >> 9 | FZA_RING_OWN_FZA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) writel_o(buf, &fp->ring_hst_rx[i].buf0_own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) fp->ring_hst_rx_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) (fp->ring_hst_rx_index + 1) % fp->ring_hst_rx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) static void fza_tx_smt(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) struct fza_buffer_tx __iomem *smt_tx_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) int i, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) u32 own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) i = fp->ring_smt_tx_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) own = readl_o(&fp->ring_smt_tx[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) if ((own & FZA_RING_OWN_MASK) == FZA_RING_OWN_FZA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) smt_tx_ptr = fp->mmio + readl_u(&fp->ring_smt_tx[i].buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) len = readl_u(&fp->ring_smt_tx[i].rmc) & FZA_RING_PBC_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (!netif_queue_stopped(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) if (dev_nit_active(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct fza_buffer_tx *skb_data_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /* Length must be a multiple of 4 as only word
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * reads are permitted!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) skb = fza_alloc_skb_irq(dev, (len + 3) & ~3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) goto err_no_skb; /* Drop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) skb_data_ptr = (struct fza_buffer_tx *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) fza_reads(smt_tx_ptr, skb_data_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) (len + 3) & ~3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) skb->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) skb_reserve(skb, 3); /* Skip over PRH. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) skb_put(skb, len - 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) dev_queue_xmit_nit(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) dev_kfree_skb_irq(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) err_no_skb:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* Queue the frame to the RMC transmit ring. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) fza_do_xmit((union fza_buffer_txp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) { .mmio_ptr = smt_tx_ptr },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) len, dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) writel_o(FZA_RING_OWN_FZA, &fp->ring_smt_tx[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) fp->ring_smt_tx_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) (fp->ring_smt_tx_index + 1) % fp->ring_smt_tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) static void fza_uns(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) u32 own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) i = fp->ring_uns_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) own = readl_o(&fp->ring_uns[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) if ((own & FZA_RING_OWN_MASK) == FZA_RING_OWN_FZA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (readl_u(&fp->ring_uns[i].id) == FZA_RING_UNS_RX_OVER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) fp->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) fp->stats.rx_over_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) writel_o(FZA_RING_OWN_FZA, &fp->ring_uns[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) fp->ring_uns_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) (fp->ring_uns_index + 1) % FZA_RING_UNS_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) static void fza_tx_flush(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) u32 own;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* Clean up the SMT TX ring. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) i = fp->ring_smt_tx_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) writel_o(FZA_RING_OWN_FZA, &fp->ring_smt_tx[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) fp->ring_smt_tx_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) (fp->ring_smt_tx_index + 1) % fp->ring_smt_tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) } while (i != fp->ring_smt_tx_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* Clean up the RMC TX ring. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) i = fp->ring_rmc_tx_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) own = readl_o(&fp->ring_rmc_tx[i].own);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) if ((own & FZA_RING_OWN_MASK) == FZA_RING_TX_OWN_RMC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u32 rmc = readl_u(&fp->ring_rmc_tx[i].rmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) writel_u(rmc | FZA_RING_TX_DTP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) &fp->ring_rmc_tx[i].rmc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) fp->ring_rmc_tx_index =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) (fp->ring_rmc_tx_index + 1) % fp->ring_rmc_tx_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) } while (i != fp->ring_rmc_tx_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /* Done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) writew_o(FZA_CONTROL_A_FLUSH_DONE, &fp->regs->control_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static irqreturn_t fza_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct net_device *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) uint int_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) /* Get interrupt events. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) int_event = readw_o(&fp->regs->int_event) & fp->int_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (int_event == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* Clear the events. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) writew_u(int_event, &fp->regs->int_event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) /* Now handle the events. The order matters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) /* Command finished interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if ((int_event & FZA_EVENT_CMD_DONE) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) fp->irq_count_cmd_done++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) spin_lock(&fp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) fp->cmd_done_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) wake_up(&fp->cmd_done_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) spin_unlock(&fp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) /* Transmit finished interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) if ((int_event & FZA_EVENT_TX_DONE) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) fp->irq_count_tx_done++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) fza_tx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /* Host receive interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if ((int_event & FZA_EVENT_RX_POLL) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) fp->irq_count_rx_poll++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) fza_rx(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) /* SMT transmit interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) if ((int_event & FZA_EVENT_SMT_TX_POLL) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) fp->irq_count_smt_tx_poll++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) fza_tx_smt(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) /* Transmit ring flush request. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if ((int_event & FZA_EVENT_FLUSH_TX) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) fp->irq_count_flush_tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) fza_tx_flush(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /* Link status change interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if ((int_event & FZA_EVENT_LINK_ST_CHG) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) uint status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) fp->irq_count_link_st_chg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) status = readw_u(&fp->regs->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (FZA_STATUS_GET_LINK(status) == FZA_LINK_ON) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) netif_carrier_on(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) pr_info("%s: link available\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) pr_info("%s: link unavailable\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) /* Unsolicited event interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if ((int_event & FZA_EVENT_UNS_POLL) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) fp->irq_count_uns_poll++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) fza_uns(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) /* State change interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if ((int_event & FZA_EVENT_STATE_CHG) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) uint status, state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) fp->irq_count_state_chg++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) status = readw_u(&fp->regs->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) state = FZA_STATUS_GET_STATE(status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) pr_debug("%s: state change: %x\n", fp->name, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) case FZA_STATE_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) case FZA_STATE_UNINITIALIZED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) netif_carrier_off(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) del_timer_sync(&fp->reset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) fp->ring_cmd_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) fp->ring_uns_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) fp->ring_rmc_tx_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) fp->ring_rmc_txd_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) fp->ring_hst_rx_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) fp->ring_smt_tx_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) fp->ring_smt_rx_index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) if (fp->state > state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) pr_info("%s: OK\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) fza_cmd_send(dev, FZA_RING_CMD_INIT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) case FZA_STATE_INITIALIZED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (fp->state > state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) fza_set_rx_mode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) fza_cmd_send(dev, FZA_RING_CMD_PARAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) case FZA_STATE_RUNNING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) case FZA_STATE_MAINTENANCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) fp->state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) fza_rx_init(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) fp->queue_active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) pr_debug("%s: queue woken\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) case FZA_STATE_HALTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) fp->queue_active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) pr_debug("%s: queue stopped\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) del_timer_sync(&fp->reset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) pr_warn("%s: halted, reason: %x\n", fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) FZA_STATUS_GET_HALT(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) fza_regs_dump(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) pr_info("%s: resetting the board...\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) fza_do_reset(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) fp->timer_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) fp->reset_timer.expires = jiffies + 45 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) add_timer(&fp->reset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) pr_warn("%s: undefined state: %x\n", fp->name, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) spin_lock(&fp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) fp->state_chg_flag = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) wake_up(&fp->state_chg_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) spin_unlock(&fp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void fza_reset_timer(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) struct fza_private *fp = from_timer(fp, t, reset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (!fp->timer_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) pr_err("%s: RESET timed out!\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) pr_info("%s: trying harder...\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) /* Assert the board reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) writew_o(FZA_RESET_INIT, &fp->regs->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) readw_o(&fp->regs->reset); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) fp->timer_state = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) fp->reset_timer.expires = jiffies + HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* Clear the board reset. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) writew_u(FZA_RESET_CLR, &fp->regs->reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) /* Enable all interrupt events we handle. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) writew_o(fp->int_mask, &fp->regs->int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) readw_o(&fp->regs->int_mask); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) fp->timer_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) fp->reset_timer.expires = jiffies + 45 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) add_timer(&fp->reset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) static int fza_set_mac_address(struct net_device *dev, void *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) static netdev_tx_t fza_start_xmit(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) unsigned int old_mask, new_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) u8 fc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) skb_push(skb, 3); /* Make room for PRH. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /* Decode FC to set PRH. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) fc = skb->data[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) skb->data[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) skb->data[1] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) skb->data[2] = FZA_PRH2_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) if ((fc & FDDI_FC_K_CLASS_MASK) == FDDI_FC_K_CLASS_SYNC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) skb->data[0] |= FZA_PRH0_FRAME_SYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) switch (fc & FDDI_FC_K_FORMAT_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) case FDDI_FC_K_FORMAT_MANAGEMENT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if ((fc & FDDI_FC_K_CONTROL_MASK) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) /* Token. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) skb->data[0] |= FZA_PRH0_TKN_TYPE_IMM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) skb->data[1] |= FZA_PRH1_TKN_SEND_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) /* SMT or MAC. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) skb->data[0] |= FZA_PRH0_TKN_TYPE_UNR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) skb->data[1] |= FZA_PRH1_TKN_SEND_UNR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) skb->data[1] |= FZA_PRH1_CRC_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) case FDDI_FC_K_FORMAT_LLC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) case FDDI_FC_K_FORMAT_FUTURE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) skb->data[0] |= FZA_PRH0_TKN_TYPE_UNR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) skb->data[1] |= FZA_PRH1_CRC_NORMAL | FZA_PRH1_TKN_SEND_UNR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) case FDDI_FC_K_FORMAT_IMPLEMENTOR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) skb->data[0] |= FZA_PRH0_TKN_TYPE_UNR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) skb->data[1] |= FZA_PRH1_TKN_SEND_ORIG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* SMT transmit interrupts may sneak frames into the RMC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) * transmit ring. We disable them while queueing a frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) * to maintain consistency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) old_mask = fp->int_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) new_mask = old_mask & ~FZA_MASK_SMT_TX_POLL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) writew_u(new_mask, &fp->regs->int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) readw_o(&fp->regs->int_mask); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) fp->int_mask = new_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) ret = fza_do_xmit((union fza_buffer_txp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) { .data_ptr = (struct fza_buffer_tx *)skb->data },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) skb->len, dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) fp->int_mask = old_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) writew_u(fp->int_mask, &fp->regs->int_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) /* Probably an SMT packet filled the remaining space,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) * so just stop the queue, but don't report it as an error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) pr_debug("%s: queue stopped\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) fp->stats.tx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) static int fza_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) struct fza_ring_cmd __iomem *ring;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) dma_addr_t dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) u32 stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) for (i = 0; i < FZA_RING_RX_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) /* We have to 512-byte-align RX buffers... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) skb = fza_alloc_skb(dev, FZA_RX_BUFFER_SIZE + 511);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if (skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) fza_skb_align(skb, 512);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) dma = dma_map_single(fp->bdev, skb->data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) FZA_RX_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) if (dma_mapping_error(fp->bdev, dma)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) skb = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (!skb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) for (--i; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) dma_unmap_single(fp->bdev, fp->rx_dma[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) FZA_RX_BUFFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) dev_kfree_skb(fp->rx_skbuff[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) fp->rx_dma[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) fp->rx_skbuff[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) fp->rx_skbuff[i] = skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) fp->rx_dma[i] = dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) ret = fza_init_send(dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* Purger and Beacon multicasts need to be supplied before PARAM. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) fza_set_rx_mode(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) spin_lock_irqsave(&fp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) fp->cmd_done_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) ring = fza_cmd_send(dev, FZA_RING_CMD_PARAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) spin_unlock_irqrestore(&fp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (!ring)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) t = wait_event_timeout(fp->cmd_done_wait, fp->cmd_done_flag, 3 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) if (fp->cmd_done_flag == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) pr_err("%s: PARAM command timed out!, state %x\n", fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) FZA_STATUS_GET_STATE(readw_u(&fp->regs->status)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) stat = readl_u(&ring->stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) if (stat != FZA_RING_STAT_SUCCESS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) pr_err("%s: PARAM command failed!, status %02x, state %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) fp->name, stat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) FZA_STATUS_GET_STATE(readw_u(&fp->regs->status)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) pr_debug("%s: PARAM: %lums elapsed\n", fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) (3 * HZ - t) * 1000 / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static int fza_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) uint state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) long t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) pr_debug("%s: queue stopped\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) del_timer_sync(&fp->reset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) spin_lock_irqsave(&fp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) fp->state = FZA_STATE_UNINITIALIZED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) fp->state_chg_flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) /* Shut the interface down. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) writew_o(FZA_CONTROL_A_SHUT, &fp->regs->control_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) readw_o(&fp->regs->control_a); /* Synchronize. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) spin_unlock_irqrestore(&fp->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) /* DEC says SHUT needs up to 10 seconds to complete. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) t = wait_event_timeout(fp->state_chg_wait, fp->state_chg_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 15 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) state = FZA_STATUS_GET_STATE(readw_o(&fp->regs->status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) if (fp->state_chg_flag == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) pr_err("%s: SHUT timed out!, state %x\n", fp->name, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (state != FZA_STATE_UNINITIALIZED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) pr_err("%s: SHUT failed!, state %x\n", fp->name, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) pr_debug("%s: SHUT: %lums elapsed\n", fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) (15 * HZ - t) * 1000 / HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) for (i = 0; i < FZA_RING_RX_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) if (fp->rx_skbuff[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) dma_unmap_single(fp->bdev, fp->rx_dma[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) FZA_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) dev_kfree_skb(fp->rx_skbuff[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) fp->rx_dma[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) fp->rx_skbuff[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) static struct net_device_stats *fza_get_stats(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) return &fp->stats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static int fza_probe(struct device *bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) static const struct net_device_ops netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) .ndo_open = fza_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) .ndo_stop = fza_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) .ndo_start_xmit = fza_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) .ndo_set_rx_mode = fza_set_rx_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) .ndo_set_mac_address = fza_set_mac_address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) .ndo_get_stats = fza_get_stats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) static int version_printed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) char rom_rev[4], fw_rev[4], rmc_rev[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) struct tc_dev *tdev = to_tc_dev(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) struct fza_cmd_init __iomem *init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) resource_size_t start, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct fza_private *fp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) uint smt_ver, pmd_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) void __iomem *mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) uint hw_addr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (!version_printed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) pr_info("%s", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) version_printed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) dev = alloc_fddidev(sizeof(*fp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) SET_NETDEV_DEV(dev, bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) dev_set_drvdata(bdev, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) fp->bdev = bdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) fp->name = dev_name(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) /* Request the I/O MEM resource. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) start = tdev->resource.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) len = tdev->resource.end - start + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) if (!request_mem_region(start, len, dev_name(bdev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) pr_err("%s: cannot reserve MMIO region\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) goto err_out_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) /* MMIO mapping setup. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) mmio = ioremap(start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) if (!mmio) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) pr_err("%s: cannot map MMIO\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) goto err_out_resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) /* Initialize the new device structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) switch (loopback) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) case FZA_LOOP_NORMAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) case FZA_LOOP_INTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) case FZA_LOOP_EXTERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) loopback = FZA_LOOP_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) fp->mmio = mmio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) dev->irq = tdev->interrupt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) pr_info("%s: DEC FDDIcontroller 700 or 700-C at 0x%08llx, irq %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) fp->name, (long long)tdev->resource.start, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) pr_debug("%s: mapped at: 0x%p\n", fp->name, mmio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) fp->regs = mmio + FZA_REG_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) fp->ring_cmd = mmio + FZA_RING_CMD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) fp->ring_uns = mmio + FZA_RING_UNS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) init_waitqueue_head(&fp->state_chg_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) init_waitqueue_head(&fp->cmd_done_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) spin_lock_init(&fp->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) fp->int_mask = FZA_MASK_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) timer_setup(&fp->reset_timer, fza_reset_timer, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) /* Sanitize the board. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) fza_regs_dump(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) fza_do_shutdown(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) ret = request_irq(dev->irq, fza_interrupt, IRQF_SHARED, fp->name, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) pr_err("%s: unable to get IRQ %d!\n", fp->name, dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) goto err_out_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) /* Enable the driver mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) writew_o(FZA_CONTROL_B_DRIVER, &fp->regs->control_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) /* For some reason transmit done interrupts can trigger during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) * reset. This avoids a division error in the handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) fp->ring_rmc_tx_size = FZA_RING_TX_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) ret = fza_reset(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) goto err_out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) ret = fza_init_send(dev, &init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) goto err_out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) fza_reads(&init->hw_addr, &hw_addr, sizeof(hw_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) memcpy(dev->dev_addr, &hw_addr, FDDI_K_ALEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) fza_reads(&init->rom_rev, &rom_rev, sizeof(rom_rev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) fza_reads(&init->fw_rev, &fw_rev, sizeof(fw_rev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) fza_reads(&init->rmc_rev, &rmc_rev, sizeof(rmc_rev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) for (i = 3; i >= 0 && rom_rev[i] == ' '; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) rom_rev[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) for (i = 3; i >= 0 && fw_rev[i] == ' '; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) fw_rev[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) for (i = 3; i >= 0 && rmc_rev[i] == ' '; i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) rmc_rev[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) fp->ring_rmc_tx = mmio + readl_u(&init->rmc_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) fp->ring_rmc_tx_size = readl_u(&init->rmc_tx_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) fp->ring_hst_rx = mmio + readl_u(&init->hst_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) fp->ring_hst_rx_size = readl_u(&init->hst_rx_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) fp->ring_smt_tx = mmio + readl_u(&init->smt_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) fp->ring_smt_tx_size = readl_u(&init->smt_tx_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) fp->ring_smt_rx = mmio + readl_u(&init->smt_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) fp->ring_smt_rx_size = readl_u(&init->smt_rx_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) fp->buffer_tx = mmio + FZA_TX_BUFFER_ADDR(readl_u(&init->rmc_tx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) fp->t_max = readl_u(&init->def_t_max);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) fp->t_req = readl_u(&init->def_t_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) fp->tvx = readl_u(&init->def_tvx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) fp->lem_threshold = readl_u(&init->lem_threshold);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) fza_reads(&init->def_station_id, &fp->station_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) sizeof(fp->station_id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) fp->rtoken_timeout = readl_u(&init->rtoken_timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) fp->ring_purger = readl_u(&init->ring_purger);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) smt_ver = readl_u(&init->smt_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) pmd_type = readl_u(&init->pmd_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) pr_debug("%s: INIT parameters:\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) pr_debug(" tx_mode: %u\n", readl_u(&init->tx_mode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) pr_debug(" hst_rx_size: %u\n", readl_u(&init->hst_rx_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) pr_debug(" rmc_rev: %.4s\n", rmc_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) pr_debug(" rom_rev: %.4s\n", rom_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) pr_debug(" fw_rev: %.4s\n", fw_rev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) pr_debug(" mop_type: %u\n", readl_u(&init->mop_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) pr_debug(" hst_rx: 0x%08x\n", readl_u(&init->hst_rx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) pr_debug(" rmc_tx: 0x%08x\n", readl_u(&init->rmc_tx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) pr_debug(" rmc_tx_size: %u\n", readl_u(&init->rmc_tx_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) pr_debug(" smt_tx: 0x%08x\n", readl_u(&init->smt_tx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) pr_debug(" smt_tx_size: %u\n", readl_u(&init->smt_tx_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) pr_debug(" smt_rx: 0x%08x\n", readl_u(&init->smt_rx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) pr_debug(" smt_rx_size: %u\n", readl_u(&init->smt_rx_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) /* TC systems are always LE, so don't bother swapping. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) pr_debug(" hw_addr: 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) (readl_u(&init->hw_addr[0]) >> 0) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) (readl_u(&init->hw_addr[0]) >> 8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) (readl_u(&init->hw_addr[0]) >> 16) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) (readl_u(&init->hw_addr[0]) >> 24) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) (readl_u(&init->hw_addr[1]) >> 0) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) (readl_u(&init->hw_addr[1]) >> 8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) (readl_u(&init->hw_addr[1]) >> 16) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) (readl_u(&init->hw_addr[1]) >> 24) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) pr_debug(" def_t_req: %u\n", readl_u(&init->def_t_req));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) pr_debug(" def_tvx: %u\n", readl_u(&init->def_tvx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) pr_debug(" def_t_max: %u\n", readl_u(&init->def_t_max));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) pr_debug(" lem_threshold: %u\n", readl_u(&init->lem_threshold));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) /* Don't bother swapping, see above. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) pr_debug(" def_station_id: 0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) (readl_u(&init->def_station_id[0]) >> 0) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) (readl_u(&init->def_station_id[0]) >> 8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) (readl_u(&init->def_station_id[0]) >> 16) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) (readl_u(&init->def_station_id[0]) >> 24) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) (readl_u(&init->def_station_id[1]) >> 0) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) (readl_u(&init->def_station_id[1]) >> 8) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) (readl_u(&init->def_station_id[1]) >> 16) & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) (readl_u(&init->def_station_id[1]) >> 24) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) pr_debug(" pmd_type_alt: %u\n", readl_u(&init->pmd_type_alt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) pr_debug(" smt_ver: %u\n", readl_u(&init->smt_ver));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) pr_debug(" rtoken_timeout: %u\n", readl_u(&init->rtoken_timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) pr_debug(" ring_purger: %u\n", readl_u(&init->ring_purger));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) pr_debug(" smt_ver_max: %u\n", readl_u(&init->smt_ver_max));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) pr_debug(" smt_ver_min: %u\n", readl_u(&init->smt_ver_min));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) pr_debug(" pmd_type: %u\n", readl_u(&init->pmd_type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) pr_info("%s: model %s, address %pMF\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) fp->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) pmd_type == FZA_PMD_TYPE_TW ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) "700-C (DEFZA-CA), ThinWire PMD selected" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) pmd_type == FZA_PMD_TYPE_STP ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) "700-C (DEFZA-CA), STP PMD selected" :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) "700 (DEFZA-AA), MMF PMD",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) pr_info("%s: ROM rev. %.4s, firmware rev. %.4s, RMC rev. %.4s, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) "SMT ver. %u\n", fp->name, rom_rev, fw_rev, rmc_rev, smt_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) /* Now that we fetched initial parameters just shut the interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) * until opened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) ret = fza_close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) goto err_out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) /* The FZA-specific entries in the device structure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) dev->netdev_ops = &netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) ret = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (ret != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) goto err_out_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) pr_info("%s: registered as %s\n", fp->name, dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) fp->name = (const char *)dev->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) get_device(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) err_out_irq:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) del_timer_sync(&fp->reset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) fza_do_shutdown(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) free_irq(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) err_out_map:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) iounmap(mmio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) err_out_resource:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) release_mem_region(start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) err_out_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) pr_err("%s: initialization failure, aborting!\n", fp->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) static int fza_remove(struct device *bdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) struct net_device *dev = dev_get_drvdata(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) struct fza_private *fp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) struct tc_dev *tdev = to_tc_dev(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) resource_size_t start, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) put_device(bdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) unregister_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) del_timer_sync(&fp->reset_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) fza_do_shutdown(fp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) free_irq(dev->irq, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) iounmap(fp->mmio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) start = tdev->resource.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) len = tdev->resource.end - start + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) release_mem_region(start, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) static struct tc_device_id const fza_tc_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) { "DEC ", "PMAF-AA " },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) MODULE_DEVICE_TABLE(tc, fza_tc_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) static struct tc_driver fza_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) .id_table = fza_tc_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) .name = "defza",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) .bus = &tc_bus_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) .probe = fza_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) .remove = fza_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) static int fza_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) return tc_register_driver(&fza_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) static void fza_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) tc_unregister_driver(&fza_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) module_init(fza_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) module_exit(fza_exit);