0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include <linux/slab.h>
0025 #include <linux/module.h>
0026 #include <linux/netdevice.h>
0027 #include <linux/etherdevice.h>
0028 #include "xp.h"
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 struct xpnet_message {
0046 u16 version;
0047 u16 embedded_bytes;
0048 u32 magic;
0049 unsigned long buf_pa;
0050 u32 size;
0051 u8 leadin_ignore;
0052 u8 tailout_ignore;
0053 unsigned char data;
0054 };
0055
0056
0057
0058
0059
0060
0061
0062 #define XPNET_MSG_SIZE XPC_MSG_PAYLOAD_MAX_SIZE
0063 #define XPNET_MSG_DATA_MAX \
0064 (XPNET_MSG_SIZE - offsetof(struct xpnet_message, data))
0065 #define XPNET_MSG_NENTRIES (PAGE_SIZE / XPC_MSG_MAX_SIZE)
0066
0067 #define XPNET_MAX_KTHREADS (XPNET_MSG_NENTRIES + 1)
0068 #define XPNET_MAX_IDLE_KTHREADS (XPNET_MSG_NENTRIES + 1)
0069
0070
0071
0072
0073
0074 #define _XPNET_VERSION(_major, _minor) (((_major) << 4) | (_minor))
0075 #define XPNET_VERSION_MAJOR(_v) ((_v) >> 4)
0076 #define XPNET_VERSION_MINOR(_v) ((_v) & 0xf)
0077
0078 #define XPNET_VERSION _XPNET_VERSION(1, 0)
0079 #define XPNET_VERSION_EMBED _XPNET_VERSION(1, 1)
0080 #define XPNET_MAGIC 0x88786984
0081
0082 #define XPNET_VALID_MSG(_m) \
0083 ((XPNET_VERSION_MAJOR(_m->version) == XPNET_VERSION_MAJOR(XPNET_VERSION)) \
0084 && (msg->magic == XPNET_MAGIC))
0085
0086 #define XPNET_DEVICE_NAME "xp0"
0087
0088
0089
0090
0091
0092
0093
0094
0095 struct xpnet_pending_msg {
0096 struct sk_buff *skb;
0097 atomic_t use_count;
0098 };
0099
0100 static struct net_device *xpnet_device;
0101
0102
0103
0104
0105
0106 static unsigned long *xpnet_broadcast_partitions;
0107
0108 static DEFINE_SPINLOCK(xpnet_broadcast_lock);
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121 #define XPNET_MAX_MTU (0x800000UL - L1_CACHE_BYTES)
0122
0123 #define XPNET_MIN_MTU 68
0124
0125 #define XPNET_DEF_MTU (0x8000UL)
0126
0127
0128
0129
0130
0131 #define XPNET_PARTID_OCTET 2
0132
0133
0134
0135 static struct device_driver xpnet_dbg_name = {
0136 .name = "xpnet"
0137 };
0138
0139 static struct device xpnet_dbg_subname = {
0140 .init_name = "",
0141 .driver = &xpnet_dbg_name
0142 };
0143
0144 static struct device *xpnet = &xpnet_dbg_subname;
0145
0146
0147
0148
0149 static void
0150 xpnet_receive(short partid, int channel, struct xpnet_message *msg)
0151 {
0152 struct sk_buff *skb;
0153 void *dst;
0154 enum xp_retval ret;
0155
0156 if (!XPNET_VALID_MSG(msg)) {
0157
0158
0159
0160 xpc_received(partid, channel, (void *)msg);
0161
0162 xpnet_device->stats.rx_errors++;
0163
0164 return;
0165 }
0166 dev_dbg(xpnet, "received 0x%lx, %d, %d, %d\n", msg->buf_pa, msg->size,
0167 msg->leadin_ignore, msg->tailout_ignore);
0168
0169
0170 skb = dev_alloc_skb(msg->size + L1_CACHE_BYTES);
0171 if (!skb) {
0172 dev_err(xpnet, "failed on dev_alloc_skb(%d)\n",
0173 msg->size + L1_CACHE_BYTES);
0174
0175 xpc_received(partid, channel, (void *)msg);
0176
0177 xpnet_device->stats.rx_errors++;
0178
0179 return;
0180 }
0181
0182
0183
0184
0185
0186
0187 skb_reserve(skb, (L1_CACHE_BYTES - ((u64)skb->data &
0188 (L1_CACHE_BYTES - 1)) +
0189 msg->leadin_ignore));
0190
0191
0192
0193
0194
0195 skb_put(skb, (msg->size - msg->leadin_ignore - msg->tailout_ignore));
0196
0197
0198
0199
0200 if ((XPNET_VERSION_MINOR(msg->version) == 1) &&
0201 (msg->embedded_bytes != 0)) {
0202 dev_dbg(xpnet, "copying embedded message. memcpy(0x%p, 0x%p, "
0203 "%lu)\n", skb->data, &msg->data,
0204 (size_t)msg->embedded_bytes);
0205
0206 skb_copy_to_linear_data(skb, &msg->data,
0207 (size_t)msg->embedded_bytes);
0208 } else {
0209 dst = (void *)((u64)skb->data & ~(L1_CACHE_BYTES - 1));
0210 dev_dbg(xpnet, "transferring buffer to the skb->data area;\n\t"
0211 "xp_remote_memcpy(0x%p, 0x%p, %u)\n", dst,
0212 (void *)msg->buf_pa, msg->size);
0213
0214 ret = xp_remote_memcpy(xp_pa(dst), msg->buf_pa, msg->size);
0215 if (ret != xpSuccess) {
0216
0217
0218
0219
0220
0221 dev_err(xpnet, "xp_remote_memcpy(0x%p, 0x%p, 0x%x) "
0222 "returned error=0x%x\n", dst,
0223 (void *)msg->buf_pa, msg->size, ret);
0224
0225 xpc_received(partid, channel, (void *)msg);
0226
0227 xpnet_device->stats.rx_errors++;
0228
0229 return;
0230 }
0231 }
0232
0233 dev_dbg(xpnet, "<skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
0234 "skb->end=0x%p skb->len=%d\n", (void *)skb->head,
0235 (void *)skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
0236 skb->len);
0237
0238 skb->protocol = eth_type_trans(skb, xpnet_device);
0239 skb->ip_summed = CHECKSUM_UNNECESSARY;
0240
0241 dev_dbg(xpnet, "passing skb to network layer\n"
0242 "\tskb->head=0x%p skb->data=0x%p skb->tail=0x%p "
0243 "skb->end=0x%p skb->len=%d\n",
0244 (void *)skb->head, (void *)skb->data, skb_tail_pointer(skb),
0245 skb_end_pointer(skb), skb->len);
0246
0247 xpnet_device->stats.rx_packets++;
0248 xpnet_device->stats.rx_bytes += skb->len + ETH_HLEN;
0249
0250 netif_rx(skb);
0251 xpc_received(partid, channel, (void *)msg);
0252 }
0253
0254
0255
0256
0257
0258 static void
0259 xpnet_connection_activity(enum xp_retval reason, short partid, int channel,
0260 void *data, void *key)
0261 {
0262 DBUG_ON(partid < 0 || partid >= xp_max_npartitions);
0263 DBUG_ON(channel != XPC_NET_CHANNEL);
0264
0265 switch (reason) {
0266 case xpMsgReceived:
0267 DBUG_ON(data == NULL);
0268
0269 xpnet_receive(partid, channel, (struct xpnet_message *)data);
0270 break;
0271
0272 case xpConnected:
0273 spin_lock_bh(&xpnet_broadcast_lock);
0274 __set_bit(partid, xpnet_broadcast_partitions);
0275 spin_unlock_bh(&xpnet_broadcast_lock);
0276
0277 netif_carrier_on(xpnet_device);
0278
0279 dev_dbg(xpnet, "%s connected to partition %d\n",
0280 xpnet_device->name, partid);
0281 break;
0282
0283 default:
0284 spin_lock_bh(&xpnet_broadcast_lock);
0285 __clear_bit(partid, xpnet_broadcast_partitions);
0286 spin_unlock_bh(&xpnet_broadcast_lock);
0287
0288 if (bitmap_empty(xpnet_broadcast_partitions,
0289 xp_max_npartitions)) {
0290 netif_carrier_off(xpnet_device);
0291 }
0292
0293 dev_dbg(xpnet, "%s disconnected from partition %d\n",
0294 xpnet_device->name, partid);
0295 break;
0296 }
0297 }
0298
0299 static int
0300 xpnet_dev_open(struct net_device *dev)
0301 {
0302 enum xp_retval ret;
0303
0304 dev_dbg(xpnet, "calling xpc_connect(%d, 0x%p, NULL, %ld, %ld, %ld, "
0305 "%ld)\n", XPC_NET_CHANNEL, xpnet_connection_activity,
0306 (unsigned long)XPNET_MSG_SIZE,
0307 (unsigned long)XPNET_MSG_NENTRIES,
0308 (unsigned long)XPNET_MAX_KTHREADS,
0309 (unsigned long)XPNET_MAX_IDLE_KTHREADS);
0310
0311 ret = xpc_connect(XPC_NET_CHANNEL, xpnet_connection_activity, NULL,
0312 XPNET_MSG_SIZE, XPNET_MSG_NENTRIES,
0313 XPNET_MAX_KTHREADS, XPNET_MAX_IDLE_KTHREADS);
0314 if (ret != xpSuccess) {
0315 dev_err(xpnet, "ifconfig up of %s failed on XPC connect, "
0316 "ret=%d\n", dev->name, ret);
0317
0318 return -ENOMEM;
0319 }
0320
0321 dev_dbg(xpnet, "ifconfig up of %s; XPC connected\n", dev->name);
0322
0323 return 0;
0324 }
0325
0326 static int
0327 xpnet_dev_stop(struct net_device *dev)
0328 {
0329 xpc_disconnect(XPC_NET_CHANNEL);
0330
0331 dev_dbg(xpnet, "ifconfig down of %s; XPC disconnected\n", dev->name);
0332
0333 return 0;
0334 }
0335
0336
0337
0338
0339
0340
0341
0342 static void
0343 xpnet_send_completed(enum xp_retval reason, short partid, int channel,
0344 void *__qm)
0345 {
0346 struct xpnet_pending_msg *queued_msg = (struct xpnet_pending_msg *)__qm;
0347
0348 DBUG_ON(queued_msg == NULL);
0349
0350 dev_dbg(xpnet, "message to %d notified with reason %d\n",
0351 partid, reason);
0352
0353 if (atomic_dec_return(&queued_msg->use_count) == 0) {
0354 dev_dbg(xpnet, "all acks for skb->head=-x%p\n",
0355 (void *)queued_msg->skb->head);
0356
0357 dev_kfree_skb_any(queued_msg->skb);
0358 kfree(queued_msg);
0359 }
0360 }
0361
0362 static void
0363 xpnet_send(struct sk_buff *skb, struct xpnet_pending_msg *queued_msg,
0364 u64 start_addr, u64 end_addr, u16 embedded_bytes, int dest_partid)
0365 {
0366 u8 msg_buffer[XPNET_MSG_SIZE];
0367 struct xpnet_message *msg = (struct xpnet_message *)&msg_buffer;
0368 u16 msg_size = sizeof(struct xpnet_message);
0369 enum xp_retval ret;
0370
0371 msg->embedded_bytes = embedded_bytes;
0372 if (unlikely(embedded_bytes != 0)) {
0373 msg->version = XPNET_VERSION_EMBED;
0374 dev_dbg(xpnet, "calling memcpy(0x%p, 0x%p, 0x%lx)\n",
0375 &msg->data, skb->data, (size_t)embedded_bytes);
0376 skb_copy_from_linear_data(skb, &msg->data,
0377 (size_t)embedded_bytes);
0378 msg_size += embedded_bytes - 1;
0379 } else {
0380 msg->version = XPNET_VERSION;
0381 }
0382 msg->magic = XPNET_MAGIC;
0383 msg->size = end_addr - start_addr;
0384 msg->leadin_ignore = (u64)skb->data - start_addr;
0385 msg->tailout_ignore = end_addr - (u64)skb_tail_pointer(skb);
0386 msg->buf_pa = xp_pa((void *)start_addr);
0387
0388 dev_dbg(xpnet, "sending XPC message to %d:%d\n"
0389 "msg->buf_pa=0x%lx, msg->size=%u, "
0390 "msg->leadin_ignore=%u, msg->tailout_ignore=%u\n",
0391 dest_partid, XPC_NET_CHANNEL, msg->buf_pa, msg->size,
0392 msg->leadin_ignore, msg->tailout_ignore);
0393
0394 atomic_inc(&queued_msg->use_count);
0395
0396 ret = xpc_send_notify(dest_partid, XPC_NET_CHANNEL, XPC_NOWAIT, msg,
0397 msg_size, xpnet_send_completed, queued_msg);
0398 if (unlikely(ret != xpSuccess))
0399 atomic_dec(&queued_msg->use_count);
0400 }
0401
0402
0403
0404
0405
0406
0407
0408
0409
0410
0411 static netdev_tx_t
0412 xpnet_dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
0413 {
0414 struct xpnet_pending_msg *queued_msg;
0415 u64 start_addr, end_addr;
0416 short dest_partid;
0417 u16 embedded_bytes = 0;
0418
0419 dev_dbg(xpnet, ">skb->head=0x%p skb->data=0x%p skb->tail=0x%p "
0420 "skb->end=0x%p skb->len=%d\n", (void *)skb->head,
0421 (void *)skb->data, skb_tail_pointer(skb), skb_end_pointer(skb),
0422 skb->len);
0423
0424 if (skb->data[0] == 0x33) {
0425 dev_kfree_skb(skb);
0426 return NETDEV_TX_OK;
0427 }
0428
0429
0430
0431
0432
0433
0434 queued_msg = kmalloc(sizeof(struct xpnet_pending_msg), GFP_ATOMIC);
0435 if (queued_msg == NULL) {
0436 dev_warn(xpnet, "failed to kmalloc %ld bytes; dropping "
0437 "packet\n", sizeof(struct xpnet_pending_msg));
0438
0439 dev->stats.tx_errors++;
0440 dev_kfree_skb(skb);
0441 return NETDEV_TX_OK;
0442 }
0443
0444
0445 start_addr = ((u64)skb->data & ~(L1_CACHE_BYTES - 1));
0446 end_addr = L1_CACHE_ALIGN((u64)skb_tail_pointer(skb));
0447
0448
0449 if (unlikely(skb->len <= XPNET_MSG_DATA_MAX)) {
0450
0451 embedded_bytes = skb->len;
0452 }
0453
0454
0455
0456
0457
0458
0459
0460
0461 atomic_set(&queued_msg->use_count, 1);
0462 queued_msg->skb = skb;
0463
0464 if (skb->data[0] == 0xff) {
0465
0466 for_each_set_bit(dest_partid, xpnet_broadcast_partitions,
0467 xp_max_npartitions) {
0468
0469 xpnet_send(skb, queued_msg, start_addr, end_addr,
0470 embedded_bytes, dest_partid);
0471 }
0472 } else {
0473 dest_partid = (short)skb->data[XPNET_PARTID_OCTET + 1];
0474 dest_partid |= (short)skb->data[XPNET_PARTID_OCTET + 0] << 8;
0475
0476 if (dest_partid >= 0 &&
0477 dest_partid < xp_max_npartitions &&
0478 test_bit(dest_partid, xpnet_broadcast_partitions) != 0) {
0479
0480 xpnet_send(skb, queued_msg, start_addr, end_addr,
0481 embedded_bytes, dest_partid);
0482 }
0483 }
0484
0485 dev->stats.tx_packets++;
0486 dev->stats.tx_bytes += skb->len;
0487
0488 if (atomic_dec_return(&queued_msg->use_count) == 0) {
0489 dev_kfree_skb(skb);
0490 kfree(queued_msg);
0491 }
0492
0493 return NETDEV_TX_OK;
0494 }
0495
0496
0497
0498
0499 static void
0500 xpnet_dev_tx_timeout(struct net_device *dev, unsigned int txqueue)
0501 {
0502 dev->stats.tx_errors++;
0503 }
0504
0505 static const struct net_device_ops xpnet_netdev_ops = {
0506 .ndo_open = xpnet_dev_open,
0507 .ndo_stop = xpnet_dev_stop,
0508 .ndo_start_xmit = xpnet_dev_hard_start_xmit,
0509 .ndo_tx_timeout = xpnet_dev_tx_timeout,
0510 .ndo_set_mac_address = eth_mac_addr,
0511 .ndo_validate_addr = eth_validate_addr,
0512 };
0513
0514 static int __init
0515 xpnet_init(void)
0516 {
0517 u8 addr[ETH_ALEN];
0518 int result;
0519
0520 if (!is_uv_system())
0521 return -ENODEV;
0522
0523 dev_info(xpnet, "registering network device %s\n", XPNET_DEVICE_NAME);
0524
0525 xpnet_broadcast_partitions = bitmap_zalloc(xp_max_npartitions,
0526 GFP_KERNEL);
0527 if (xpnet_broadcast_partitions == NULL)
0528 return -ENOMEM;
0529
0530
0531
0532
0533
0534 xpnet_device = alloc_netdev(0, XPNET_DEVICE_NAME, NET_NAME_UNKNOWN,
0535 ether_setup);
0536 if (xpnet_device == NULL) {
0537 bitmap_free(xpnet_broadcast_partitions);
0538 return -ENOMEM;
0539 }
0540
0541 netif_carrier_off(xpnet_device);
0542
0543 xpnet_device->netdev_ops = &xpnet_netdev_ops;
0544 xpnet_device->mtu = XPNET_DEF_MTU;
0545 xpnet_device->min_mtu = XPNET_MIN_MTU;
0546 xpnet_device->max_mtu = XPNET_MAX_MTU;
0547
0548 memset(addr, 0, sizeof(addr));
0549
0550
0551
0552
0553
0554 addr[0] = 0x02;
0555
0556 addr[XPNET_PARTID_OCTET + 1] = xp_partition_id;
0557 addr[XPNET_PARTID_OCTET + 0] = (xp_partition_id >> 8);
0558 eth_hw_addr_set(xpnet_device, addr);
0559
0560
0561
0562
0563
0564 xpnet_device->flags &= ~IFF_MULTICAST;
0565
0566
0567
0568
0569
0570
0571 xpnet_device->features = NETIF_F_HW_CSUM;
0572
0573 result = register_netdev(xpnet_device);
0574 if (result != 0) {
0575 free_netdev(xpnet_device);
0576 bitmap_free(xpnet_broadcast_partitions);
0577 }
0578
0579 return result;
0580 }
0581
0582 module_init(xpnet_init);
0583
0584 static void __exit
0585 xpnet_exit(void)
0586 {
0587 dev_info(xpnet, "unregistering network device %s\n",
0588 xpnet_device[0].name);
0589
0590 unregister_netdev(xpnet_device);
0591 free_netdev(xpnet_device);
0592 bitmap_free(xpnet_broadcast_partitions);
0593 }
0594
0595 module_exit(xpnet_exit);
0596
0597 MODULE_AUTHOR("Silicon Graphics, Inc.");
0598 MODULE_DESCRIPTION("Cross Partition Network adapter (XPNET)");
0599 MODULE_LICENSE("GPL");