xref: /openbmc/linux/drivers/block/aoe/aoenet.c (revision 5ee9cd065836e5934710ca35653bce7905add20b)
1  /* Copyright (c) 2013 Coraid, Inc.  See COPYING for GPL terms. */
2  /*
3   * aoenet.c
4   * Ethernet portion of AoE driver
5   */
6  
7  #include <linux/gfp.h>
8  #include <linux/hdreg.h>
9  #include <linux/blkdev.h>
10  #include <linux/netdevice.h>
11  #include <linux/moduleparam.h>
12  #include <net/net_namespace.h>
13  #include <asm/unaligned.h>
14  #include "aoe.h"
15  
16  #define NECODES 5
17  
18  static char *aoe_errlist[] =
19  {
20  	"no such error",
21  	"unrecognized command code",
22  	"bad argument parameter",
23  	"device unavailable",
24  	"config string present",
25  	"unsupported version"
26  };
27  
28  enum {
29  	IFLISTSZ = 1024,
30  };
31  
32  static char aoe_iflist[IFLISTSZ];
33  module_param_string(aoe_iflist, aoe_iflist, IFLISTSZ, 0600);
34  MODULE_PARM_DESC(aoe_iflist, "aoe_iflist=dev1[,dev2...]");
35  
36  static wait_queue_head_t txwq;
37  static struct ktstate kts;
38  
39  #ifndef MODULE
aoe_iflist_setup(char * str)40  static int __init aoe_iflist_setup(char *str)
41  {
42  	strncpy(aoe_iflist, str, IFLISTSZ);
43  	aoe_iflist[IFLISTSZ - 1] = '\0';
44  	return 1;
45  }
46  
47  __setup("aoe_iflist=", aoe_iflist_setup);
48  #endif
49  
50  static spinlock_t txlock;
51  static struct sk_buff_head skbtxq;
52  
53  /* enters with txlock held */
54  static int
tx(int id)55  tx(int id) __must_hold(&txlock)
56  {
57  	struct sk_buff *skb;
58  	struct net_device *ifp;
59  
60  	while ((skb = skb_dequeue(&skbtxq))) {
61  		spin_unlock_irq(&txlock);
62  		ifp = skb->dev;
63  		if (dev_queue_xmit(skb) == NET_XMIT_DROP && net_ratelimit())
64  			pr_warn("aoe: packet could not be sent on %s.  %s\n",
65  				ifp ? ifp->name : "netif",
66  				"consider increasing tx_queue_len");
67  		dev_put(ifp);
68  		spin_lock_irq(&txlock);
69  	}
70  	return 0;
71  }
72  
73  int
is_aoe_netif(struct net_device * ifp)74  is_aoe_netif(struct net_device *ifp)
75  {
76  	register char *p, *q;
77  	register int len;
78  
79  	if (aoe_iflist[0] == '\0')
80  		return 1;
81  
82  	p = aoe_iflist + strspn(aoe_iflist, WHITESPACE);
83  	for (; *p; p = q + strspn(q, WHITESPACE)) {
84  		q = p + strcspn(p, WHITESPACE);
85  		if (q != p)
86  			len = q - p;
87  		else
88  			len = strlen(p); /* last token in aoe_iflist */
89  
90  		if (strlen(ifp->name) == len && !strncmp(ifp->name, p, len))
91  			return 1;
92  		if (q == p)
93  			break;
94  	}
95  
96  	return 0;
97  }
98  
99  int
set_aoe_iflist(const char __user * user_str,size_t size)100  set_aoe_iflist(const char __user *user_str, size_t size)
101  {
102  	if (size >= IFLISTSZ)
103  		return -EINVAL;
104  
105  	if (copy_from_user(aoe_iflist, user_str, size)) {
106  		printk(KERN_INFO "aoe: copy from user failed\n");
107  		return -EFAULT;
108  	}
109  	aoe_iflist[size] = 0x00;
110  	return 0;
111  }
112  
113  void
aoenet_xmit(struct sk_buff_head * queue)114  aoenet_xmit(struct sk_buff_head *queue)
115  {
116  	struct sk_buff *skb, *tmp;
117  	ulong flags;
118  
119  	skb_queue_walk_safe(queue, skb, tmp) {
120  		__skb_unlink(skb, queue);
121  		spin_lock_irqsave(&txlock, flags);
122  		skb_queue_tail(&skbtxq, skb);
123  		spin_unlock_irqrestore(&txlock, flags);
124  		wake_up(&txwq);
125  	}
126  }
127  
128  /*
129   * (1) len doesn't include the header by default.  I want this.
130   */
131  static int
aoenet_rcv(struct sk_buff * skb,struct net_device * ifp,struct packet_type * pt,struct net_device * orig_dev)132  aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev)
133  {
134  	struct aoe_hdr *h;
135  	struct aoe_atahdr *ah;
136  	u32 n;
137  	int sn;
138  
139  	if (dev_net(ifp) != &init_net)
140  		goto exit;
141  
142  	skb = skb_share_check(skb, GFP_ATOMIC);
143  	if (skb == NULL)
144  		return 0;
145  	if (!is_aoe_netif(ifp))
146  		goto exit;
147  	skb_push(skb, ETH_HLEN);	/* (1) */
148  	sn = sizeof(*h) + sizeof(*ah);
149  	if (skb->len >= sn) {
150  		sn -= skb_headlen(skb);
151  		if (sn > 0 && !__pskb_pull_tail(skb, sn))
152  			goto exit;
153  	}
154  	h = (struct aoe_hdr *) skb->data;
155  	n = get_unaligned_be32(&h->tag);
156  	if ((h->verfl & AOEFL_RSP) == 0 || (n & 1<<31))
157  		goto exit;
158  
159  	if (h->verfl & AOEFL_ERR) {
160  		n = h->err;
161  		if (n > NECODES)
162  			n = 0;
163  		if (net_ratelimit())
164  			printk(KERN_ERR
165  				"%s%d.%d@%s; ecode=%d '%s'\n",
166  				"aoe: error packet from ",
167  				get_unaligned_be16(&h->major),
168  				h->minor, skb->dev->name,
169  				h->err, aoe_errlist[n]);
170  		goto exit;
171  	}
172  
173  	switch (h->cmd) {
174  	case AOECMD_ATA:
175  		/* ata_rsp may keep skb for later processing or give it back */
176  		skb = aoecmd_ata_rsp(skb);
177  		break;
178  	case AOECMD_CFG:
179  		aoecmd_cfg_rsp(skb);
180  		break;
181  	default:
182  		if (h->cmd >= AOECMD_VEND_MIN)
183  			break;	/* don't complain about vendor commands */
184  		pr_info("aoe: unknown AoE command type 0x%02x\n", h->cmd);
185  		break;
186  	}
187  
188  	if (!skb)
189  		return 0;
190  exit:
191  	dev_kfree_skb(skb);
192  	return 0;
193  }
194  
195  static struct packet_type aoe_pt __read_mostly = {
196  	.type = __constant_htons(ETH_P_AOE),
197  	.func = aoenet_rcv,
198  };
199  
200  int __init
aoenet_init(void)201  aoenet_init(void)
202  {
203  	skb_queue_head_init(&skbtxq);
204  	init_waitqueue_head(&txwq);
205  	spin_lock_init(&txlock);
206  	kts.lock = &txlock;
207  	kts.fn = tx;
208  	kts.waitq = &txwq;
209  	kts.id = 0;
210  	snprintf(kts.name, sizeof(kts.name), "aoe_tx%d", kts.id);
211  	if (aoe_ktstart(&kts))
212  		return -EAGAIN;
213  	dev_add_pack(&aoe_pt);
214  	return 0;
215  }
216  
217  void
aoenet_exit(void)218  aoenet_exit(void)
219  {
220  	aoe_ktstop(&kts);
221  	skb_queue_purge(&skbtxq);
222  	dev_remove_pack(&aoe_pt);
223  }
224  
225