Blame view

drivers/net/rionet.c 13.7 KB
f89efd523   Matt Porter   [PATCH] Add rapid...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  /*
   * rionet - Ethernet driver over RapidIO messaging services
   *
   * Copyright 2005 MontaVista Software, Inc.
   * Matt Porter <mporter@kernel.crashing.org>
   *
   * This program is free software; you can redistribute  it and/or modify it
   * under  the terms of  the GNU General  Public License as published by the
   * Free Software Foundation;  either version 2 of the  License, or (at your
   * option) any later version.
   */
  
  #include <linux/module.h>
  #include <linux/kernel.h>
  #include <linux/dma-mapping.h>
  #include <linux/delay.h>
  #include <linux/rio.h>
  #include <linux/rio_drv.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
19
  #include <linux/slab.h>
f89efd523   Matt Porter   [PATCH] Add rapid...
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
  #include <linux/rio_ids.h>
  
  #include <linux/netdevice.h>
  #include <linux/etherdevice.h>
  #include <linux/skbuff.h>
  #include <linux/crc32.h>
  #include <linux/ethtool.h>
  
  #define DRV_NAME        "rionet"
  #define DRV_VERSION     "0.2"
  #define DRV_AUTHOR      "Matt Porter <mporter@kernel.crashing.org>"
  #define DRV_DESC        "Ethernet over RapidIO"
  
  MODULE_AUTHOR(DRV_AUTHOR);
  MODULE_DESCRIPTION(DRV_DESC);
  MODULE_LICENSE("GPL");
  
  #define RIONET_DEFAULT_MSGLEVEL \
  			(NETIF_MSG_DRV          | \
  			 NETIF_MSG_LINK         | \
  			 NETIF_MSG_RX_ERR       | \
  			 NETIF_MSG_TX_ERR)
  
  #define RIONET_DOORBELL_JOIN	0x1000
  #define RIONET_DOORBELL_LEAVE	0x1001
  
  #define RIONET_MAILBOX		0
  
  #define RIONET_TX_RING_SIZE	CONFIG_RIONET_TX_SIZE
  #define RIONET_RX_RING_SIZE	CONFIG_RIONET_RX_SIZE
  
  static LIST_HEAD(rionet_peers);
  
  struct rionet_private {
  	struct rio_mport *mport;
  	struct sk_buff *rx_skb[RIONET_RX_RING_SIZE];
  	struct sk_buff *tx_skb[RIONET_TX_RING_SIZE];
f89efd523   Matt Porter   [PATCH] Add rapid...
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  	int rx_slot;
  	int tx_slot;
  	int tx_cnt;
  	int ack_slot;
  	spinlock_t lock;
  	spinlock_t tx_lock;
  	u32 msg_enable;
  };
  
  struct rionet_peer {
  	struct list_head node;
  	struct rio_dev *rdev;
  	struct resource *res;
  };
  
  static int rionet_check = 0;
  static int rionet_capable = 1;
  
  /*
411c94038   Anand Gadiyar   trivial: fix typo...
76
   * This is a fast lookup table for translating TX
f89efd523   Matt Porter   [PATCH] Add rapid...
77
78
79
80
   * Ethernet packets into a destination RIO device. It
   * could be made into a hash table to save memory depending
   * on system trade-offs.
   */
e04232360   Zhang Wei   [RAPIDIO] Auto-pr...
81
  static struct rio_dev **rionet_active;
f89efd523   Matt Porter   [PATCH] Add rapid...
82

284fb68d0   Alexandre Bounine   rapidio: fix use ...
83
84
85
  #define is_rionet_capable(src_ops, dst_ops)			\
  			((src_ops & RIO_SRC_OPS_DATA_MSG) &&	\
  			 (dst_ops & RIO_DST_OPS_DATA_MSG) &&	\
f89efd523   Matt Porter   [PATCH] Add rapid...
86
87
88
  			 (src_ops & RIO_SRC_OPS_DOORBELL) &&	\
  			 (dst_ops & RIO_DST_OPS_DOORBELL))
  #define dev_rionet_capable(dev) \
284fb68d0   Alexandre Bounine   rapidio: fix use ...
89
  	is_rionet_capable(dev->src_ops, dev->dst_ops)
f89efd523   Matt Porter   [PATCH] Add rapid...
90

e0c87bd95   Alexandre Bounine   drivers/net/rione...
91
92
  #define RIONET_MAC_MATCH(x)	(!memcmp((x), "\00\01\00\01", 4))
  #define RIONET_GET_DESTID(x)	((*((u8 *)x + 4) << 8) | *((u8 *)x + 5))
f89efd523   Matt Porter   [PATCH] Add rapid...
93

f89efd523   Matt Porter   [PATCH] Add rapid...
94
95
96
97
  static int rionet_rx_clean(struct net_device *ndev)
  {
  	int i;
  	int error = 0;
4cf1653aa   Wang Chen   netdevice: safe c...
98
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
99
100
101
102
103
104
105
106
107
108
109
110
111
  	void *data;
  
  	i = rnet->rx_slot;
  
  	do {
  		if (!rnet->rx_skb[i])
  			continue;
  
  		if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX)))
  			break;
  
  		rnet->rx_skb[i]->data = data;
  		skb_put(rnet->rx_skb[i], RIO_MAX_MSG_SIZE);
f89efd523   Matt Porter   [PATCH] Add rapid...
112
113
114
115
116
  		rnet->rx_skb[i]->protocol =
  		    eth_type_trans(rnet->rx_skb[i], ndev);
  		error = netif_rx(rnet->rx_skb[i]);
  
  		if (error == NET_RX_DROP) {
09f75cd7b   Jeff Garzik   [NET] drivers/net...
117
  			ndev->stats.rx_dropped++;
f89efd523   Matt Porter   [PATCH] Add rapid...
118
  		} else {
09f75cd7b   Jeff Garzik   [NET] drivers/net...
119
120
  			ndev->stats.rx_packets++;
  			ndev->stats.rx_bytes += RIO_MAX_MSG_SIZE;
f89efd523   Matt Porter   [PATCH] Add rapid...
121
122
123
124
125
126
127
128
129
130
  		}
  
  	} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != rnet->rx_slot);
  
  	return i;
  }
  
  static void rionet_rx_fill(struct net_device *ndev, int end)
  {
  	int i;
4cf1653aa   Wang Chen   netdevice: safe c...
131
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
  
  	i = rnet->rx_slot;
  	do {
  		rnet->rx_skb[i] = dev_alloc_skb(RIO_MAX_MSG_SIZE);
  
  		if (!rnet->rx_skb[i])
  			break;
  
  		rio_add_inb_buffer(rnet->mport, RIONET_MAILBOX,
  				   rnet->rx_skb[i]->data);
  	} while ((i = (i + 1) % RIONET_RX_RING_SIZE) != end);
  
  	rnet->rx_slot = i;
  }
  
  static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev,
  			       struct rio_dev *rdev)
  {
4cf1653aa   Wang Chen   netdevice: safe c...
150
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
151
152
153
  
  	rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len);
  	rnet->tx_skb[rnet->tx_slot] = skb;
09f75cd7b   Jeff Garzik   [NET] drivers/net...
154
155
  	ndev->stats.tx_packets++;
  	ndev->stats.tx_bytes += skb->len;
f89efd523   Matt Porter   [PATCH] Add rapid...
156
157
158
159
160
161
162
163
  
  	if (++rnet->tx_cnt == RIONET_TX_RING_SIZE)
  		netif_stop_queue(ndev);
  
  	++rnet->tx_slot;
  	rnet->tx_slot &= (RIONET_TX_RING_SIZE - 1);
  
  	if (netif_msg_tx_queued(rnet))
8df8a4753   David S. Miller   rionet: Remove po...
164
165
166
  		printk(KERN_INFO "%s: queued skb len %8.8x
  ", DRV_NAME,
  		       skb->len);
f89efd523   Matt Porter   [PATCH] Add rapid...
167
168
169
170
171
172
173
  
  	return 0;
  }
  
  static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
  {
  	int i;
4cf1653aa   Wang Chen   netdevice: safe c...
174
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
  	struct ethhdr *eth = (struct ethhdr *)skb->data;
  	u16 destid;
  	unsigned long flags;
  
  	local_irq_save(flags);
  	if (!spin_trylock(&rnet->tx_lock)) {
  		local_irq_restore(flags);
  		return NETDEV_TX_LOCKED;
  	}
  
  	if ((rnet->tx_cnt + 1) > RIONET_TX_RING_SIZE) {
  		netif_stop_queue(ndev);
  		spin_unlock_irqrestore(&rnet->tx_lock, flags);
  		printk(KERN_ERR "%s: BUG! Tx Ring full when queue awake!
  ",
  		       ndev->name);
  		return NETDEV_TX_BUSY;
  	}
abfc89c7b   Tobias Klauser   net: rionet: Use ...
193
  	if (is_multicast_ether_addr(eth->h_dest)) {
e04232360   Zhang Wei   [RAPIDIO] Auto-pr...
194
195
  		for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size);
  				i++)
f89efd523   Matt Porter   [PATCH] Add rapid...
196
197
198
199
200
201
202
203
204
205
  			if (rionet_active[i])
  				rionet_queue_tx_msg(skb, ndev,
  						    rionet_active[i]);
  	} else if (RIONET_MAC_MATCH(eth->h_dest)) {
  		destid = RIONET_GET_DESTID(eth->h_dest);
  		if (rionet_active[destid])
  			rionet_queue_tx_msg(skb, ndev, rionet_active[destid]);
  	}
  
  	spin_unlock_irqrestore(&rnet->tx_lock, flags);
6ed106549   Patrick McHardy   net: use NETDEV_T...
206
  	return NETDEV_TX_OK;
f89efd523   Matt Porter   [PATCH] Add rapid...
207
208
209
210
211
212
  }
  
  static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid,
  			       u16 info)
  {
  	struct net_device *ndev = dev_id;
4cf1653aa   Wang Chen   netdevice: safe c...
213
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
  	struct rionet_peer *peer;
  
  	if (netif_msg_intr(rnet))
  		printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x",
  		       DRV_NAME, sid, tid, info);
  	if (info == RIONET_DOORBELL_JOIN) {
  		if (!rionet_active[sid]) {
  			list_for_each_entry(peer, &rionet_peers, node) {
  				if (peer->rdev->destid == sid)
  					rionet_active[sid] = peer->rdev;
  			}
  			rio_mport_send_doorbell(mport, sid,
  						RIONET_DOORBELL_JOIN);
  		}
  	} else if (info == RIONET_DOORBELL_LEAVE) {
  		rionet_active[sid] = NULL;
  	} else {
  		if (netif_msg_intr(rnet))
  			printk(KERN_WARNING "%s: unhandled doorbell
  ",
  			       DRV_NAME);
  	}
  }
  
  static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
  {
  	int n;
  	struct net_device *ndev = dev_id;
4cf1653aa   Wang Chen   netdevice: safe c...
242
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
  
  	if (netif_msg_intr(rnet))
  		printk(KERN_INFO "%s: inbound message event, mbox %d slot %d
  ",
  		       DRV_NAME, mbox, slot);
  
  	spin_lock(&rnet->lock);
  	if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot)
  		rionet_rx_fill(ndev, n);
  	spin_unlock(&rnet->lock);
  }
  
  static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot)
  {
  	struct net_device *ndev = dev_id;
4cf1653aa   Wang Chen   netdevice: safe c...
258
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
  
  	spin_lock(&rnet->lock);
  
  	if (netif_msg_intr(rnet))
  		printk(KERN_INFO
  		       "%s: outbound message event, mbox %d slot %d
  ",
  		       DRV_NAME, mbox, slot);
  
  	while (rnet->tx_cnt && (rnet->ack_slot != slot)) {
  		/* dma unmap single */
  		dev_kfree_skb_irq(rnet->tx_skb[rnet->ack_slot]);
  		rnet->tx_skb[rnet->ack_slot] = NULL;
  		++rnet->ack_slot;
  		rnet->ack_slot &= (RIONET_TX_RING_SIZE - 1);
  		rnet->tx_cnt--;
  	}
  
  	if (rnet->tx_cnt < RIONET_TX_RING_SIZE)
  		netif_wake_queue(ndev);
  
  	spin_unlock(&rnet->lock);
  }
  
  static int rionet_open(struct net_device *ndev)
  {
  	int i, rc = 0;
  	struct rionet_peer *peer, *tmp;
4cf1653aa   Wang Chen   netdevice: safe c...
287
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
  
  	if (netif_msg_ifup(rnet))
  		printk(KERN_INFO "%s: open
  ", DRV_NAME);
  
  	if ((rc = rio_request_inb_dbell(rnet->mport,
  					(void *)ndev,
  					RIONET_DOORBELL_JOIN,
  					RIONET_DOORBELL_LEAVE,
  					rionet_dbell_event)) < 0)
  		goto out;
  
  	if ((rc = rio_request_inb_mbox(rnet->mport,
  				       (void *)ndev,
  				       RIONET_MAILBOX,
  				       RIONET_RX_RING_SIZE,
  				       rionet_inb_msg_event)) < 0)
  		goto out;
  
  	if ((rc = rio_request_outb_mbox(rnet->mport,
  					(void *)ndev,
  					RIONET_MAILBOX,
  					RIONET_TX_RING_SIZE,
  					rionet_outb_msg_event)) < 0)
  		goto out;
  
  	/* Initialize inbound message ring */
  	for (i = 0; i < RIONET_RX_RING_SIZE; i++)
  		rnet->rx_skb[i] = NULL;
  	rnet->rx_slot = 0;
  	rionet_rx_fill(ndev, 0);
  
  	rnet->tx_slot = 0;
  	rnet->tx_cnt = 0;
  	rnet->ack_slot = 0;
  
  	netif_carrier_on(ndev);
  	netif_start_queue(ndev);
  
  	list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
  		if (!(peer->res = rio_request_outb_dbell(peer->rdev,
  							 RIONET_DOORBELL_JOIN,
  							 RIONET_DOORBELL_LEAVE)))
  		{
  			printk(KERN_ERR "%s: error requesting doorbells
  ",
  			       DRV_NAME);
  			continue;
  		}
284fb68d0   Alexandre Bounine   rapidio: fix use ...
337
338
  		/* Send a join message */
  		rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN);
f89efd523   Matt Porter   [PATCH] Add rapid...
339
340
341
342
343
344
345
346
  	}
  
        out:
  	return rc;
  }
  
  static int rionet_close(struct net_device *ndev)
  {
4cf1653aa   Wang Chen   netdevice: safe c...
347
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
348
349
350
351
352
353
354
355
356
357
358
  	struct rionet_peer *peer, *tmp;
  	int i;
  
  	if (netif_msg_ifup(rnet))
  		printk(KERN_INFO "%s: close
  ", DRV_NAME);
  
  	netif_stop_queue(ndev);
  	netif_carrier_off(ndev);
  
  	for (i = 0; i < RIONET_RX_RING_SIZE; i++)
aaff1e190   Wei Yongjun   drivers/net/rione...
359
  		kfree_skb(rnet->rx_skb[i]);
f89efd523   Matt Porter   [PATCH] Add rapid...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  
  	list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
  		if (rionet_active[peer->rdev->destid]) {
  			rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE);
  			rionet_active[peer->rdev->destid] = NULL;
  		}
  		rio_release_outb_dbell(peer->rdev, peer->res);
  	}
  
  	rio_release_inb_dbell(rnet->mport, RIONET_DOORBELL_JOIN,
  			      RIONET_DOORBELL_LEAVE);
  	rio_release_inb_mbox(rnet->mport, RIONET_MAILBOX);
  	rio_release_outb_mbox(rnet->mport, RIONET_MAILBOX);
  
  	return 0;
  }
  
  static void rionet_remove(struct rio_dev *rdev)
  {
55caa9241   Yinglin Luan   rionet: fix NULL ...
379
  	struct net_device *ndev = rio_get_drvdata(rdev);
f89efd523   Matt Porter   [PATCH] Add rapid...
380
  	struct rionet_peer *peer, *tmp;
e04232360   Zhang Wei   [RAPIDIO] Auto-pr...
381
  	free_pages((unsigned long)rionet_active, rdev->net->hport->sys_size ?
388b78adc   Alexandre Bounine   rapidio: modify c...
382
  					__fls(sizeof(void *)) + 4 : 0);
f89efd523   Matt Porter   [PATCH] Add rapid...
383
  	unregister_netdev(ndev);
22138d307   Kulikov Vasiliy   rionet: use free_...
384
  	free_netdev(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
385
386
387
388
389
390
391
392
393
394
  
  	list_for_each_entry_safe(peer, tmp, &rionet_peers, node) {
  		list_del(&peer->node);
  		kfree(peer);
  	}
  }
  
  static void rionet_get_drvinfo(struct net_device *ndev,
  			       struct ethtool_drvinfo *info)
  {
4cf1653aa   Wang Chen   netdevice: safe c...
395
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
396
397
398
399
400
401
402
403
404
  
  	strcpy(info->driver, DRV_NAME);
  	strcpy(info->version, DRV_VERSION);
  	strcpy(info->fw_version, "n/a");
  	strcpy(info->bus_info, rnet->mport->name);
  }
  
  static u32 rionet_get_msglevel(struct net_device *ndev)
  {
4cf1653aa   Wang Chen   netdevice: safe c...
405
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
406
407
408
409
410
411
  
  	return rnet->msg_enable;
  }
  
  static void rionet_set_msglevel(struct net_device *ndev, u32 value)
  {
4cf1653aa   Wang Chen   netdevice: safe c...
412
  	struct rionet_private *rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
413
414
415
  
  	rnet->msg_enable = value;
  }
7282d491e   Jeff Garzik   drivers/net: cons...
416
  static const struct ethtool_ops rionet_ethtool_ops = {
f89efd523   Matt Porter   [PATCH] Add rapid...
417
418
419
420
421
  	.get_drvinfo = rionet_get_drvinfo,
  	.get_msglevel = rionet_get_msglevel,
  	.set_msglevel = rionet_set_msglevel,
  	.get_link = ethtool_op_get_link,
  };
a33a2bb3c   Alexander Beregalov   rionet: convert t...
422
423
424
425
426
427
428
429
  static const struct net_device_ops rionet_netdev_ops = {
  	.ndo_open		= rionet_open,
  	.ndo_stop		= rionet_close,
  	.ndo_start_xmit		= rionet_start_xmit,
  	.ndo_change_mtu		= eth_change_mtu,
  	.ndo_validate_addr	= eth_validate_addr,
  	.ndo_set_mac_address	= eth_mac_addr,
  };
55caa9241   Yinglin Luan   rionet: fix NULL ...
430
  static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev)
f89efd523   Matt Porter   [PATCH] Add rapid...
431
432
  {
  	int rc = 0;
f89efd523   Matt Porter   [PATCH] Add rapid...
433
434
  	struct rionet_private *rnet;
  	u16 device_id;
e04232360   Zhang Wei   [RAPIDIO] Auto-pr...
435
  	rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL,
388b78adc   Alexandre Bounine   rapidio: modify c...
436
  			mport->sys_size ? __fls(sizeof(void *)) + 4 : 0);
e04232360   Zhang Wei   [RAPIDIO] Auto-pr...
437
438
439
440
441
442
  	if (!rionet_active) {
  		rc = -ENOMEM;
  		goto out;
  	}
  	memset((void *)rionet_active, 0, sizeof(void *) *
  				RIO_MAX_ROUTE_ENTRIES(mport->sys_size));
f89efd523   Matt Porter   [PATCH] Add rapid...
443
  	/* Set up private area */
4cf1653aa   Wang Chen   netdevice: safe c...
444
  	rnet = netdev_priv(ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
445
446
447
448
449
450
451
452
453
454
  	rnet->mport = mport;
  
  	/* Set the default MAC address */
  	device_id = rio_local_get_device_id(mport);
  	ndev->dev_addr[0] = 0x00;
  	ndev->dev_addr[1] = 0x01;
  	ndev->dev_addr[2] = 0x00;
  	ndev->dev_addr[3] = 0x01;
  	ndev->dev_addr[4] = device_id >> 8;
  	ndev->dev_addr[5] = device_id & 0xff;
a33a2bb3c   Alexander Beregalov   rionet: convert t...
455
  	ndev->netdev_ops = &rionet_netdev_ops;
f89efd523   Matt Porter   [PATCH] Add rapid...
456
457
458
  	ndev->mtu = RIO_MAX_MSG_SIZE - 14;
  	ndev->features = NETIF_F_LLTX;
  	SET_ETHTOOL_OPS(ndev, &rionet_ethtool_ops);
f89efd523   Matt Porter   [PATCH] Add rapid...
459
460
461
462
463
464
465
466
  	spin_lock_init(&rnet->lock);
  	spin_lock_init(&rnet->tx_lock);
  
  	rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL;
  
  	rc = register_netdev(ndev);
  	if (rc != 0)
  		goto out;
e174961ca   Johannes Berg   net: convert prin...
467
468
  	printk("%s: %s %s Version %s, MAC %pM
  ",
f89efd523   Matt Porter   [PATCH] Add rapid...
469
470
471
472
  	       ndev->name,
  	       DRV_NAME,
  	       DRV_DESC,
  	       DRV_VERSION,
e174961ca   Johannes Berg   net: convert prin...
473
  	       ndev->dev_addr);
f89efd523   Matt Porter   [PATCH] Add rapid...
474
475
476
477
478
479
480
481
482
483
484
  
        out:
  	return rc;
  }
  
  /*
   * XXX Make multi-net safe
   */
  static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id)
  {
  	int rc = -ENODEV;
284fb68d0   Alexandre Bounine   rapidio: fix use ...
485
  	u32 lsrc_ops, ldst_ops;
f89efd523   Matt Porter   [PATCH] Add rapid...
486
  	struct rionet_peer *peer;
55caa9241   Yinglin Luan   rionet: fix NULL ...
487
  	struct net_device *ndev = NULL;
f89efd523   Matt Porter   [PATCH] Add rapid...
488
489
490
491
  
  	/* If local device is not rionet capable, give up quickly */
  	if (!rionet_capable)
  		goto out;
55caa9241   Yinglin Luan   rionet: fix NULL ...
492
493
494
495
496
497
498
499
500
  	/* Allocate our net_device structure */
  	ndev = alloc_etherdev(sizeof(struct rionet_private));
  	if (ndev == NULL) {
  		printk(KERN_INFO "%s: could not allocate ethernet device.
  ",
  		       DRV_NAME);
  		rc = -ENOMEM;
  		goto out;
  	}
f89efd523   Matt Porter   [PATCH] Add rapid...
501
502
503
504
505
506
  	/*
  	 * First time through, make sure local device is rionet
  	 * capable, setup netdev,  and set flags so this is skipped
  	 * on later probes
  	 */
  	if (!rionet_check) {
f89efd523   Matt Porter   [PATCH] Add rapid...
507
508
509
510
  		rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR,
  					 &lsrc_ops);
  		rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR,
  					 &ldst_ops);
284fb68d0   Alexandre Bounine   rapidio: fix use ...
511
  		if (!is_rionet_capable(lsrc_ops, ldst_ops)) {
f89efd523   Matt Porter   [PATCH] Add rapid...
512
513
514
515
516
517
518
519
  			printk(KERN_ERR
  			       "%s: local device is not network capable
  ",
  			       DRV_NAME);
  			rionet_check = 1;
  			rionet_capable = 0;
  			goto out;
  		}
55caa9241   Yinglin Luan   rionet: fix NULL ...
520
  		rc = rionet_setup_netdev(rdev->net->hport, ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
  		rionet_check = 1;
  	}
  
  	/*
  	 * If the remote device has mailbox/doorbell capabilities,
  	 * add it to the peer list.
  	 */
  	if (dev_rionet_capable(rdev)) {
  		if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) {
  			rc = -ENOMEM;
  			goto out;
  		}
  		peer->rdev = rdev;
  		list_add_tail(&peer->node, &rionet_peers);
  	}
55caa9241   Yinglin Luan   rionet: fix NULL ...
536
  	rio_set_drvdata(rdev, ndev);
f89efd523   Matt Porter   [PATCH] Add rapid...
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
        out:
  	return rc;
  }
  
  static struct rio_device_id rionet_id_table[] = {
  	{RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}
  };
  
  static struct rio_driver rionet_driver = {
  	.name = "rionet",
  	.id_table = rionet_id_table,
  	.probe = rionet_probe,
  	.remove = rionet_remove,
  };
  
  static int __init rionet_init(void)
  {
  	return rio_register_driver(&rionet_driver);
  }
  
  static void __exit rionet_exit(void)
  {
  	rio_unregister_driver(&rionet_driver);
  }
2f809985d   Alexandre Bounine   rapidio: modify s...
561
  late_initcall(rionet_init);
f89efd523   Matt Porter   [PATCH] Add rapid...
562
  module_exit(rionet_exit);