Blame view
drivers/net/rionet.c
18.8 KB
f89efd523 [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 include cleanup: ... |
19 |
#include <linux/slab.h> |
f89efd523 [PATCH] Add rapid... |
20 21 22 23 24 25 26 |
#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> |
f41e2472b rapidio/rionet: a... |
27 |
#include <linux/reboot.h> |
f89efd523 [PATCH] Add rapid... |
28 29 |
#define DRV_NAME "rionet" |
2fb717ec3 rapidio/rionet: r... |
30 |
#define DRV_VERSION "0.3" |
f89efd523 [PATCH] Add rapid... |
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
#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 |
2fb717ec3 rapidio/rionet: r... |
51 |
#define RIONET_MAX_NETS 8 |
92444bb36 rapidio/rionet: a... |
52 53 |
#define RIONET_MSG_SIZE RIO_MAX_MSG_SIZE #define RIONET_MAX_MTU (RIONET_MSG_SIZE - ETH_HLEN) |
f89efd523 [PATCH] Add rapid... |
54 55 56 57 58 |
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 [PATCH] Add rapid... |
59 60 61 62 63 64 65 |
int rx_slot; int tx_slot; int tx_cnt; int ack_slot; spinlock_t lock; spinlock_t tx_lock; u32 msg_enable; |
34ed2ebb6 rapidio/rionet: a... |
66 |
bool open; |
f89efd523 [PATCH] Add rapid... |
67 68 69 70 71 72 73 |
}; struct rionet_peer { struct list_head node; struct rio_dev *rdev; struct resource *res; }; |
2fb717ec3 rapidio/rionet: r... |
74 75 76 |
struct rionet_net { struct net_device *ndev; struct list_head peers; |
34ed2ebb6 rapidio/rionet: a... |
77 |
spinlock_t lock; /* net info access lock */ |
2fb717ec3 rapidio/rionet: r... |
78 79 80 |
struct rio_dev **active; int nact; /* number of active peers */ }; |
f89efd523 [PATCH] Add rapid... |
81 |
|
2fb717ec3 rapidio/rionet: r... |
82 |
static struct rionet_net nets[RIONET_MAX_NETS]; |
f89efd523 [PATCH] Add rapid... |
83 |
|
284fb68d0 rapidio: fix use ... |
84 85 86 |
#define is_rionet_capable(src_ops, dst_ops) \ ((src_ops & RIO_SRC_OPS_DATA_MSG) && \ (dst_ops & RIO_DST_OPS_DATA_MSG) && \ |
f89efd523 [PATCH] Add rapid... |
87 88 89 |
(src_ops & RIO_SRC_OPS_DOORBELL) && \ (dst_ops & RIO_DST_OPS_DOORBELL)) #define dev_rionet_capable(dev) \ |
284fb68d0 rapidio: fix use ... |
90 |
is_rionet_capable(dev->src_ops, dev->dst_ops) |
f89efd523 [PATCH] Add rapid... |
91 |
|
e0c87bd95 drivers/net/rione... |
92 93 |
#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 [PATCH] Add rapid... |
94 |
|
f89efd523 [PATCH] Add rapid... |
95 96 97 98 |
static int rionet_rx_clean(struct net_device *ndev) { int i; int error = 0; |
4cf1653aa netdevice: safe c... |
99 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
100 101 102 103 104 105 106 107 108 109 110 111 112 |
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 [PATCH] Add rapid... |
113 114 115 116 117 |
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 [NET] drivers/net... |
118 |
ndev->stats.rx_dropped++; |
f89efd523 [PATCH] Add rapid... |
119 |
} else { |
09f75cd7b [NET] drivers/net... |
120 121 |
ndev->stats.rx_packets++; ndev->stats.rx_bytes += RIO_MAX_MSG_SIZE; |
f89efd523 [PATCH] Add rapid... |
122 123 124 125 126 127 128 129 130 131 |
} } 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 netdevice: safe c... |
132 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 |
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 netdevice: safe c... |
151 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
152 153 154 |
rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len); rnet->tx_skb[rnet->tx_slot] = skb; |
09f75cd7b [NET] drivers/net... |
155 156 |
ndev->stats.tx_packets++; ndev->stats.tx_bytes += skb->len; |
f89efd523 [PATCH] Add rapid... |
157 158 159 160 161 162 163 164 |
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 rionet: Remove po... |
165 166 167 |
printk(KERN_INFO "%s: queued skb len %8.8x ", DRV_NAME, skb->len); |
f89efd523 [PATCH] Add rapid... |
168 169 170 171 172 173 174 |
return 0; } static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) { int i; |
4cf1653aa netdevice: safe c... |
175 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
176 177 178 |
struct ethhdr *eth = (struct ethhdr *)skb->data; u16 destid; unsigned long flags; |
7c4a6106d rapidio/rionet: f... |
179 |
int add_num = 1; |
f89efd523 [PATCH] Add rapid... |
180 |
|
a6086a893 drivers: net: rem... |
181 |
spin_lock_irqsave(&rnet->tx_lock, flags); |
f89efd523 [PATCH] Add rapid... |
182 |
|
7c4a6106d rapidio/rionet: f... |
183 |
if (is_multicast_ether_addr(eth->h_dest)) |
2fb717ec3 rapidio/rionet: r... |
184 |
add_num = nets[rnet->mport->id].nact; |
7c4a6106d rapidio/rionet: f... |
185 186 |
if ((rnet->tx_cnt + add_num) > RIONET_TX_RING_SIZE) { |
f89efd523 [PATCH] Add rapid... |
187 188 189 190 191 192 193 |
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 net: rionet: Use ... |
194 |
if (is_multicast_ether_addr(eth->h_dest)) { |
7c4a6106d rapidio/rionet: f... |
195 |
int count = 0; |
2fb717ec3 rapidio/rionet: r... |
196 |
|
e04232360 [RAPIDIO] Auto-pr... |
197 198 |
for (i = 0; i < RIO_MAX_ROUTE_ENTRIES(rnet->mport->sys_size); i++) |
2fb717ec3 rapidio/rionet: r... |
199 |
if (nets[rnet->mport->id].active[i]) { |
f89efd523 [PATCH] Add rapid... |
200 |
rionet_queue_tx_msg(skb, ndev, |
2fb717ec3 rapidio/rionet: r... |
201 |
nets[rnet->mport->id].active[i]); |
7c4a6106d rapidio/rionet: f... |
202 203 204 205 |
if (count) atomic_inc(&skb->users); count++; } |
f89efd523 [PATCH] Add rapid... |
206 207 |
} else if (RIONET_MAC_MATCH(eth->h_dest)) { destid = RIONET_GET_DESTID(eth->h_dest); |
2fb717ec3 rapidio/rionet: r... |
208 209 210 |
if (nets[rnet->mport->id].active[destid]) rionet_queue_tx_msg(skb, ndev, nets[rnet->mport->id].active[destid]); |
e6161d642 rapidio/rionet: r... |
211 212 213 214 215 216 217 218 219 220 221 |
else { /* * If the target device was removed from the list of * active peers but we still have TX packets targeting * it just report sending a packet to the target * (without actual packet transfer). */ dev_kfree_skb_any(skb); ndev->stats.tx_packets++; ndev->stats.tx_bytes += skb->len; } |
f89efd523 [PATCH] Add rapid... |
222 223 224 |
} spin_unlock_irqrestore(&rnet->tx_lock, flags); |
6ed106549 net: use NETDEV_T... |
225 |
return NETDEV_TX_OK; |
f89efd523 [PATCH] Add rapid... |
226 227 228 229 230 231 |
} 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 netdevice: safe c... |
232 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
233 |
struct rionet_peer *peer; |
34ed2ebb6 rapidio/rionet: a... |
234 |
unsigned char netid = rnet->mport->id; |
f89efd523 [PATCH] Add rapid... |
235 236 237 238 239 |
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) { |
34ed2ebb6 rapidio/rionet: a... |
240 241 242 |
if (!nets[netid].active[sid]) { spin_lock(&nets[netid].lock); list_for_each_entry(peer, &nets[netid].peers, node) { |
7c4a6106d rapidio/rionet: f... |
243 |
if (peer->rdev->destid == sid) { |
34ed2ebb6 rapidio/rionet: a... |
244 245 |
nets[netid].active[sid] = peer->rdev; nets[netid].nact++; |
7c4a6106d rapidio/rionet: f... |
246 |
} |
f89efd523 [PATCH] Add rapid... |
247 |
} |
34ed2ebb6 rapidio/rionet: a... |
248 |
spin_unlock(&nets[netid].lock); |
f89efd523 [PATCH] Add rapid... |
249 250 251 252 |
rio_mport_send_doorbell(mport, sid, RIONET_DOORBELL_JOIN); } } else if (info == RIONET_DOORBELL_LEAVE) { |
34ed2ebb6 rapidio/rionet: a... |
253 254 255 256 257 258 |
spin_lock(&nets[netid].lock); if (nets[netid].active[sid]) { nets[netid].active[sid] = NULL; nets[netid].nact--; } spin_unlock(&nets[netid].lock); |
f89efd523 [PATCH] Add rapid... |
259 260 261 262 263 264 265 266 267 268 269 270 |
} 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 netdevice: safe c... |
271 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 |
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 netdevice: safe c... |
287 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
288 |
|
36915976e rapidio/rionet: f... |
289 |
spin_lock(&rnet->tx_lock); |
f89efd523 [PATCH] Add rapid... |
290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 |
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); |
36915976e rapidio/rionet: f... |
308 |
spin_unlock(&rnet->tx_lock); |
f89efd523 [PATCH] Add rapid... |
309 310 311 312 313 |
} static int rionet_open(struct net_device *ndev) { int i, rc = 0; |
34ed2ebb6 rapidio/rionet: a... |
314 |
struct rionet_peer *peer; |
4cf1653aa netdevice: safe c... |
315 |
struct rionet_private *rnet = netdev_priv(ndev); |
34ed2ebb6 rapidio/rionet: a... |
316 317 |
unsigned char netid = rnet->mport->id; unsigned long flags; |
f89efd523 [PATCH] Add rapid... |
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
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); |
34ed2ebb6 rapidio/rionet: a... |
356 357 |
spin_lock_irqsave(&nets[netid].lock, flags); list_for_each_entry(peer, &nets[netid].peers, node) { |
284fb68d0 rapidio: fix use ... |
358 359 |
/* Send a join message */ rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); |
f89efd523 [PATCH] Add rapid... |
360 |
} |
34ed2ebb6 rapidio/rionet: a... |
361 362 |
spin_unlock_irqrestore(&nets[netid].lock, flags); rnet->open = true; |
f89efd523 [PATCH] Add rapid... |
363 364 365 366 367 368 369 |
out: return rc; } static int rionet_close(struct net_device *ndev) { |
4cf1653aa netdevice: safe c... |
370 |
struct rionet_private *rnet = netdev_priv(ndev); |
34ed2ebb6 rapidio/rionet: a... |
371 372 373 |
struct rionet_peer *peer; unsigned char netid = rnet->mport->id; unsigned long flags; |
f89efd523 [PATCH] Add rapid... |
374 375 376 |
int i; if (netif_msg_ifup(rnet)) |
2fb717ec3 rapidio/rionet: r... |
377 378 |
printk(KERN_INFO "%s: close %s ", DRV_NAME, ndev->name); |
f89efd523 [PATCH] Add rapid... |
379 380 381 |
netif_stop_queue(ndev); netif_carrier_off(ndev); |
34ed2ebb6 rapidio/rionet: a... |
382 |
rnet->open = false; |
f89efd523 [PATCH] Add rapid... |
383 384 |
for (i = 0; i < RIONET_RX_RING_SIZE; i++) |
aaff1e190 drivers/net/rione... |
385 |
kfree_skb(rnet->rx_skb[i]); |
f89efd523 [PATCH] Add rapid... |
386 |
|
34ed2ebb6 rapidio/rionet: a... |
387 388 389 |
spin_lock_irqsave(&nets[netid].lock, flags); list_for_each_entry(peer, &nets[netid].peers, node) { if (nets[netid].active[peer->rdev->destid]) { |
f89efd523 [PATCH] Add rapid... |
390 |
rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE); |
34ed2ebb6 rapidio/rionet: a... |
391 |
nets[netid].active[peer->rdev->destid] = NULL; |
f89efd523 [PATCH] Add rapid... |
392 |
} |
34ed2ebb6 rapidio/rionet: a... |
393 394 |
if (peer->res) rio_release_outb_dbell(peer->rdev, peer->res); |
f89efd523 [PATCH] Add rapid... |
395 |
} |
34ed2ebb6 rapidio/rionet: a... |
396 |
spin_unlock_irqrestore(&nets[netid].lock, flags); |
f89efd523 [PATCH] Add rapid... |
397 398 399 400 401 402 403 404 |
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; } |
71db87ba5 bus: subsys: upda... |
405 |
static void rionet_remove_dev(struct device *dev, struct subsys_interface *sif) |
f89efd523 [PATCH] Add rapid... |
406 |
{ |
e6161d642 rapidio/rionet: r... |
407 |
struct rio_dev *rdev = to_rio_dev(dev); |
2fb717ec3 rapidio/rionet: r... |
408 |
unsigned char netid = rdev->net->hport->id; |
34ed2ebb6 rapidio/rionet: a... |
409 410 411 |
struct rionet_peer *peer; int state, found = 0; unsigned long flags; |
f89efd523 [PATCH] Add rapid... |
412 |
|
34ed2ebb6 rapidio/rionet: a... |
413 414 415 416 417 418 419 420 421 422 423 424 425 |
if (!dev_rionet_capable(rdev)) return; spin_lock_irqsave(&nets[netid].lock, flags); list_for_each_entry(peer, &nets[netid].peers, node) { if (peer->rdev == rdev) { list_del(&peer->node); if (nets[netid].active[rdev->destid]) { state = atomic_read(&rdev->state); if (state != RIO_DEVICE_GONE && state != RIO_DEVICE_INITIALIZING) { rio_send_doorbell(rdev, RIONET_DOORBELL_LEAVE); |
e6161d642 rapidio/rionet: r... |
426 |
} |
34ed2ebb6 rapidio/rionet: a... |
427 428 |
nets[netid].active[rdev->destid] = NULL; nets[netid].nact--; |
e6161d642 rapidio/rionet: r... |
429 |
} |
34ed2ebb6 rapidio/rionet: a... |
430 431 |
found = 1; break; |
e6161d642 rapidio/rionet: r... |
432 |
} |
f89efd523 [PATCH] Add rapid... |
433 |
} |
34ed2ebb6 rapidio/rionet: a... |
434 435 436 437 438 439 440 |
spin_unlock_irqrestore(&nets[netid].lock, flags); if (found) { if (peer->res) rio_release_outb_dbell(rdev, peer->res); kfree(peer); } |
f89efd523 [PATCH] Add rapid... |
441 442 443 444 445 |
} static void rionet_get_drvinfo(struct net_device *ndev, struct ethtool_drvinfo *info) { |
4cf1653aa netdevice: safe c... |
446 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
447 |
|
7826d43f2 ethtool: fix drvi... |
448 449 450 451 |
strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); strlcpy(info->version, DRV_VERSION, sizeof(info->version)); strlcpy(info->fw_version, "n/a", sizeof(info->fw_version)); strlcpy(info->bus_info, rnet->mport->name, sizeof(info->bus_info)); |
f89efd523 [PATCH] Add rapid... |
452 453 454 455 |
} static u32 rionet_get_msglevel(struct net_device *ndev) { |
4cf1653aa netdevice: safe c... |
456 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
457 458 459 460 461 462 |
return rnet->msg_enable; } static void rionet_set_msglevel(struct net_device *ndev, u32 value) { |
4cf1653aa netdevice: safe c... |
463 |
struct rionet_private *rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
464 465 466 |
rnet->msg_enable = value; } |
92444bb36 rapidio/rionet: a... |
467 468 469 470 471 472 473 474 475 476 477 |
static int rionet_change_mtu(struct net_device *ndev, int new_mtu) { if ((new_mtu < 68) || (new_mtu > RIONET_MAX_MTU)) { printk(KERN_ERR "%s: Invalid MTU size %d ", ndev->name, new_mtu); return -EINVAL; } ndev->mtu = new_mtu; return 0; } |
7282d491e drivers/net: cons... |
478 |
static const struct ethtool_ops rionet_ethtool_ops = { |
f89efd523 [PATCH] Add rapid... |
479 480 481 482 483 |
.get_drvinfo = rionet_get_drvinfo, .get_msglevel = rionet_get_msglevel, .set_msglevel = rionet_set_msglevel, .get_link = ethtool_op_get_link, }; |
a33a2bb3c rionet: convert t... |
484 485 486 487 |
static const struct net_device_ops rionet_netdev_ops = { .ndo_open = rionet_open, .ndo_stop = rionet_close, .ndo_start_xmit = rionet_start_xmit, |
92444bb36 rapidio/rionet: a... |
488 |
.ndo_change_mtu = rionet_change_mtu, |
a33a2bb3c rionet: convert t... |
489 490 491 |
.ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, }; |
55caa9241 rionet: fix NULL ... |
492 |
static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) |
f89efd523 [PATCH] Add rapid... |
493 494 |
{ int rc = 0; |
f89efd523 [PATCH] Add rapid... |
495 496 |
struct rionet_private *rnet; u16 device_id; |
acc656323 rionet: fix page ... |
497 498 |
const size_t rionet_active_bytes = sizeof(void *) * RIO_MAX_ROUTE_ENTRIES(mport->sys_size); |
f89efd523 [PATCH] Add rapid... |
499 |
|
2fb717ec3 rapidio/rionet: r... |
500 501 502 |
nets[mport->id].active = (struct rio_dev **)__get_free_pages(GFP_KERNEL, get_order(rionet_active_bytes)); if (!nets[mport->id].active) { |
e04232360 [RAPIDIO] Auto-pr... |
503 504 505 |
rc = -ENOMEM; goto out; } |
2fb717ec3 rapidio/rionet: r... |
506 |
memset((void *)nets[mport->id].active, 0, rionet_active_bytes); |
e04232360 [RAPIDIO] Auto-pr... |
507 |
|
f89efd523 [PATCH] Add rapid... |
508 |
/* Set up private area */ |
4cf1653aa netdevice: safe c... |
509 |
rnet = netdev_priv(ndev); |
f89efd523 [PATCH] Add rapid... |
510 |
rnet->mport = mport; |
34ed2ebb6 rapidio/rionet: a... |
511 |
rnet->open = false; |
f89efd523 [PATCH] Add rapid... |
512 513 514 515 516 517 518 519 520 |
/* 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 rionet: convert t... |
521 |
ndev->netdev_ops = &rionet_netdev_ops; |
92444bb36 rapidio/rionet: a... |
522 |
ndev->mtu = RIONET_MAX_MTU; |
f89efd523 [PATCH] Add rapid... |
523 |
ndev->features = NETIF_F_LLTX; |
2aaf308b9 rapidio: rework d... |
524 |
SET_NETDEV_DEV(ndev, &mport->dev); |
7ad24ea4b net: get rid of S... |
525 |
ndev->ethtool_ops = &rionet_ethtool_ops; |
f89efd523 [PATCH] Add rapid... |
526 |
|
f89efd523 [PATCH] Add rapid... |
527 528 529 530 531 532 |
spin_lock_init(&rnet->lock); spin_lock_init(&rnet->tx_lock); rnet->msg_enable = RIONET_DEFAULT_MSGLEVEL; rc = register_netdev(ndev); |
34ed2ebb6 rapidio/rionet: a... |
533 534 535 |
if (rc != 0) { free_pages((unsigned long)nets[mport->id].active, get_order(rionet_active_bytes)); |
f89efd523 [PATCH] Add rapid... |
536 |
goto out; |
34ed2ebb6 rapidio/rionet: a... |
537 |
} |
f89efd523 [PATCH] Add rapid... |
538 |
|
2fb717ec3 rapidio/rionet: r... |
539 540 |
printk(KERN_INFO "%s: %s %s Version %s, MAC %pM, %s ", |
f89efd523 [PATCH] Add rapid... |
541 542 543 544 |
ndev->name, DRV_NAME, DRV_DESC, DRV_VERSION, |
2fb717ec3 rapidio/rionet: r... |
545 546 |
ndev->dev_addr, mport->name); |
f89efd523 [PATCH] Add rapid... |
547 548 549 550 |
out: return rc; } |
e6161d642 rapidio/rionet: r... |
551 |
static int rionet_add_dev(struct device *dev, struct subsys_interface *sif) |
f89efd523 [PATCH] Add rapid... |
552 553 |
{ int rc = -ENODEV; |
284fb68d0 rapidio: fix use ... |
554 |
u32 lsrc_ops, ldst_ops; |
f89efd523 [PATCH] Add rapid... |
555 |
struct rionet_peer *peer; |
55caa9241 rionet: fix NULL ... |
556 |
struct net_device *ndev = NULL; |
e6161d642 rapidio/rionet: r... |
557 |
struct rio_dev *rdev = to_rio_dev(dev); |
2fb717ec3 rapidio/rionet: r... |
558 |
unsigned char netid = rdev->net->hport->id; |
f89efd523 [PATCH] Add rapid... |
559 |
|
2fb717ec3 rapidio/rionet: r... |
560 561 |
if (netid >= RIONET_MAX_NETS) return rc; |
f89efd523 [PATCH] Add rapid... |
562 563 |
/* |
e6161d642 rapidio/rionet: r... |
564 565 566 |
* If first time through this net, make sure local device is rionet * capable and setup netdev (this step will be skipped in later probes * on the same net). |
f89efd523 [PATCH] Add rapid... |
567 |
*/ |
34ed2ebb6 rapidio/rionet: a... |
568 |
if (!nets[netid].ndev) { |
f89efd523 [PATCH] Add rapid... |
569 570 571 572 |
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 rapidio: fix use ... |
573 |
if (!is_rionet_capable(lsrc_ops, ldst_ops)) { |
f89efd523 [PATCH] Add rapid... |
574 |
printk(KERN_ERR |
2fb717ec3 rapidio/rionet: r... |
575 576 577 |
"%s: local device %s is not network capable ", DRV_NAME, rdev->net->hport->name); |
f89efd523 [PATCH] Add rapid... |
578 579 |
goto out; } |
2fb717ec3 rapidio/rionet: r... |
580 581 582 583 584 585 |
/* Allocate our net_device structure */ ndev = alloc_etherdev(sizeof(struct rionet_private)); if (ndev == NULL) { rc = -ENOMEM; goto out; } |
34ed2ebb6 rapidio/rionet: a... |
586 |
|
55caa9241 rionet: fix NULL ... |
587 |
rc = rionet_setup_netdev(rdev->net->hport, ndev); |
e6161d642 rapidio/rionet: r... |
588 589 590 591 |
if (rc) { printk(KERN_ERR "%s: failed to setup netdev (rc=%d) ", DRV_NAME, rc); |
34ed2ebb6 rapidio/rionet: a... |
592 |
free_netdev(ndev); |
e6161d642 rapidio/rionet: r... |
593 594 |
goto out; } |
2fb717ec3 rapidio/rionet: r... |
595 |
INIT_LIST_HEAD(&nets[netid].peers); |
34ed2ebb6 rapidio/rionet: a... |
596 |
spin_lock_init(&nets[netid].lock); |
2fb717ec3 rapidio/rionet: r... |
597 |
nets[netid].nact = 0; |
34ed2ebb6 rapidio/rionet: a... |
598 599 |
nets[netid].ndev = ndev; } |
f89efd523 [PATCH] Add rapid... |
600 601 602 603 604 605 |
/* * If the remote device has mailbox/doorbell capabilities, * add it to the peer list. */ if (dev_rionet_capable(rdev)) { |
34ed2ebb6 rapidio/rionet: a... |
606 607 608 609 610 611 612 |
struct rionet_private *rnet; unsigned long flags; rnet = netdev_priv(nets[netid].ndev); peer = kzalloc(sizeof(*peer), GFP_KERNEL); if (!peer) { |
f89efd523 [PATCH] Add rapid... |
613 614 615 616 |
rc = -ENOMEM; goto out; } peer->rdev = rdev; |
34ed2ebb6 rapidio/rionet: a... |
617 618 619 620 621 622 623 624 625 626 627 628 |
peer->res = rio_request_outb_dbell(peer->rdev, RIONET_DOORBELL_JOIN, RIONET_DOORBELL_LEAVE); if (!peer->res) { pr_err("%s: error requesting doorbells ", DRV_NAME); kfree(peer); rc = -ENOMEM; goto out; } spin_lock_irqsave(&nets[netid].lock, flags); |
2fb717ec3 rapidio/rionet: r... |
629 |
list_add_tail(&peer->node, &nets[netid].peers); |
34ed2ebb6 rapidio/rionet: a... |
630 631 632 633 634 635 636 637 |
spin_unlock_irqrestore(&nets[netid].lock, flags); pr_debug("%s: %s add peer %s ", DRV_NAME, __func__, rio_name(rdev)); /* If netdev is already opened, send join request to new peer */ if (rnet->open) rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); |
f89efd523 [PATCH] Add rapid... |
638 |
} |
e6161d642 rapidio/rionet: r... |
639 640 |
return 0; out: |
f89efd523 [PATCH] Add rapid... |
641 642 |
return rc; } |
f41e2472b rapidio/rionet: a... |
643 644 645 |
static int rionet_shutdown(struct notifier_block *nb, unsigned long code, void *unused) { |
34ed2ebb6 rapidio/rionet: a... |
646 647 |
struct rionet_peer *peer; unsigned long flags; |
f41e2472b rapidio/rionet: a... |
648 649 650 651 652 653 654 655 |
int i; pr_debug("%s: %s ", DRV_NAME, __func__); for (i = 0; i < RIONET_MAX_NETS; i++) { if (!nets[i].ndev) continue; |
34ed2ebb6 rapidio/rionet: a... |
656 657 |
spin_lock_irqsave(&nets[i].lock, flags); list_for_each_entry(peer, &nets[i].peers, node) { |
f41e2472b rapidio/rionet: a... |
658 659 660 661 662 663 |
if (nets[i].active[peer->rdev->destid]) { rio_send_doorbell(peer->rdev, RIONET_DOORBELL_LEAVE); nets[i].active[peer->rdev->destid] = NULL; } } |
34ed2ebb6 rapidio/rionet: a... |
664 |
spin_unlock_irqrestore(&nets[i].lock, flags); |
f41e2472b rapidio/rionet: a... |
665 666 667 668 |
} return NOTIFY_DONE; } |
b7dfca8bd rapidio/rionet: a... |
669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 |
static void rionet_remove_mport(struct device *dev, struct class_interface *class_intf) { struct rio_mport *mport = to_rio_mport(dev); struct net_device *ndev; int id = mport->id; pr_debug("%s %s ", __func__, mport->name); WARN(nets[id].nact, "%s called when connected to %d peers ", __func__, nets[id].nact); WARN(!nets[id].ndev, "%s called for mport without NDEV ", __func__); if (nets[id].ndev) { ndev = nets[id].ndev; netif_stop_queue(ndev); unregister_netdev(ndev); free_pages((unsigned long)nets[id].active, get_order(sizeof(void *) * RIO_MAX_ROUTE_ENTRIES(mport->sys_size))); nets[id].active = NULL; free_netdev(ndev); nets[id].ndev = NULL; } } |
e6161d642 rapidio/rionet: r... |
699 |
#ifdef MODULE |
f89efd523 [PATCH] Add rapid... |
700 |
static struct rio_device_id rionet_id_table[] = { |
e6161d642 rapidio/rionet: r... |
701 702 |
{RIO_DEVICE(RIO_ANY_ID, RIO_ANY_ID)}, { 0, } /* terminate list */ |
f89efd523 [PATCH] Add rapid... |
703 |
}; |
e6161d642 rapidio/rionet: r... |
704 705 706 707 708 709 710 711 |
MODULE_DEVICE_TABLE(rapidio, rionet_id_table); #endif static struct subsys_interface rionet_interface = { .name = "rionet", .subsys = &rio_bus_type, .add_dev = rionet_add_dev, .remove_dev = rionet_remove_dev, |
f89efd523 [PATCH] Add rapid... |
712 |
}; |
f41e2472b rapidio/rionet: a... |
713 714 715 |
static struct notifier_block rionet_notifier = { .notifier_call = rionet_shutdown, }; |
b7dfca8bd rapidio/rionet: a... |
716 717 718 719 720 721 |
/* the rio_mport_interface is used to handle local mport devices */ static struct class_interface rio_mport_interface __refdata = { .class = &rio_mport_class, .add_dev = NULL, .remove_dev = rionet_remove_mport, }; |
f89efd523 [PATCH] Add rapid... |
722 723 |
static int __init rionet_init(void) { |
f41e2472b rapidio/rionet: a... |
724 725 726 727 728 729 730 731 732 |
int ret; ret = register_reboot_notifier(&rionet_notifier); if (ret) { pr_err("%s: failed to register reboot notifier (err=%d) ", DRV_NAME, ret); return ret; } |
b7dfca8bd rapidio/rionet: a... |
733 734 735 736 737 738 739 740 |
ret = class_interface_register(&rio_mport_interface); if (ret) { pr_err("%s: class_interface_register error: %d ", DRV_NAME, ret); return ret; } |
e6161d642 rapidio/rionet: r... |
741 |
return subsys_interface_register(&rionet_interface); |
f89efd523 [PATCH] Add rapid... |
742 743 744 745 |
} static void __exit rionet_exit(void) { |
f41e2472b rapidio/rionet: a... |
746 |
unregister_reboot_notifier(&rionet_notifier); |
e6161d642 rapidio/rionet: r... |
747 |
subsys_interface_unregister(&rionet_interface); |
b7dfca8bd rapidio/rionet: a... |
748 |
class_interface_unregister(&rio_mport_interface); |
f89efd523 [PATCH] Add rapid... |
749 |
} |
2f809985d rapidio: modify s... |
750 |
late_initcall(rionet_init); |
f89efd523 [PATCH] Add rapid... |
751 |
module_exit(rionet_exit); |