Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * NET3:    Fibre Channel device handling subroutines
0004  *
0005  *      Vineet Abraham <vma@iol.unh.edu>
0006  *      v 1.0 03/22/99
0007  */
0008 
0009 #include <linux/uaccess.h>
0010 #include <linux/types.h>
0011 #include <linux/kernel.h>
0012 #include <linux/string.h>
0013 #include <linux/mm.h>
0014 #include <linux/socket.h>
0015 #include <linux/in.h>
0016 #include <linux/inet.h>
0017 #include <linux/netdevice.h>
0018 #include <linux/fcdevice.h>
0019 #include <linux/skbuff.h>
0020 #include <linux/errno.h>
0021 #include <linux/timer.h>
0022 #include <linux/net.h>
0023 #include <linux/proc_fs.h>
0024 #include <linux/init.h>
0025 #include <linux/export.h>
0026 #include <net/arp.h>
0027 
0028 /*
0029  *  Put the headers on a Fibre Channel packet.
0030  */
0031 
0032 static int fc_header(struct sk_buff *skb, struct net_device *dev,
0033              unsigned short type,
0034              const void *daddr, const void *saddr, unsigned int len)
0035 {
0036     struct fch_hdr *fch;
0037     int hdr_len;
0038 
0039     /*
0040      * Add the 802.2 SNAP header if IP as the IPv4 code calls
0041      * dev->hard_header directly.
0042      */
0043     if (type == ETH_P_IP || type == ETH_P_ARP)
0044     {
0045         struct fcllc *fcllc;
0046 
0047         hdr_len = sizeof(struct fch_hdr) + sizeof(struct fcllc);
0048         fch = skb_push(skb, hdr_len);
0049         fcllc = (struct fcllc *)(fch+1);
0050         fcllc->dsap = fcllc->ssap = EXTENDED_SAP;
0051         fcllc->llc = UI_CMD;
0052         fcllc->protid[0] = fcllc->protid[1] = fcllc->protid[2] = 0x00;
0053         fcllc->ethertype = htons(type);
0054     }
0055     else
0056     {
0057         hdr_len = sizeof(struct fch_hdr);
0058         fch = skb_push(skb, hdr_len);
0059     }
0060 
0061     if(saddr)
0062         memcpy(fch->saddr,saddr,dev->addr_len);
0063     else
0064         memcpy(fch->saddr,dev->dev_addr,dev->addr_len);
0065 
0066     if(daddr)
0067     {
0068         memcpy(fch->daddr,daddr,dev->addr_len);
0069         return hdr_len;
0070     }
0071     return -hdr_len;
0072 }
0073 
0074 static const struct header_ops fc_header_ops = {
0075     .create  = fc_header,
0076 };
0077 
0078 static void fc_setup(struct net_device *dev)
0079 {
0080     dev->header_ops     = &fc_header_ops;
0081     dev->type       = ARPHRD_IEEE802;
0082     dev->hard_header_len    = FC_HLEN;
0083     dev->mtu        = 2024;
0084     dev->addr_len       = FC_ALEN;
0085     dev->tx_queue_len   = 100; /* Long queues on fc */
0086     dev->flags      = IFF_BROADCAST;
0087 
0088     memset(dev->broadcast, 0xFF, FC_ALEN);
0089 }
0090 
0091 /**
0092  * alloc_fcdev - Register fibre channel device
0093  * @sizeof_priv: Size of additional driver-private structure to be allocated
0094  *  for this fibre channel device
0095  *
0096  * Fill in the fields of the device structure with fibre channel-generic values.
0097  *
0098  * Constructs a new net device, complete with a private data area of
0099  * size @sizeof_priv.  A 32-byte (not bit) alignment is enforced for
0100  * this private data area.
0101  */
0102 struct net_device *alloc_fcdev(int sizeof_priv)
0103 {
0104     return alloc_netdev(sizeof_priv, "fc%d", NET_NAME_UNKNOWN, fc_setup);
0105 }
0106 EXPORT_SYMBOL(alloc_fcdev);