ARM64: DTS: Fix Firefly board audio driver
[firefly-linux-kernel-4.4.55.git] / drivers / firewire / net.c
index 7bdb6fe63236f16a3fc3f5d780c69202418b2af3..b9d2f76a0cf7a036a2794436db34887bf75590fe 100644 (file)
@@ -73,13 +73,13 @@ struct rfc2734_header {
 
 #define fwnet_get_hdr_lf(h)            (((h)->w0 & 0xc0000000) >> 30)
 #define fwnet_get_hdr_ether_type(h)    (((h)->w0 & 0x0000ffff))
-#define fwnet_get_hdr_dg_size(h)       (((h)->w0 & 0x0fff0000) >> 16)
+#define fwnet_get_hdr_dg_size(h)       ((((h)->w0 & 0x0fff0000) >> 16) + 1)
 #define fwnet_get_hdr_fg_off(h)                (((h)->w0 & 0x00000fff))
 #define fwnet_get_hdr_dgl(h)           (((h)->w1 & 0xffff0000) >> 16)
 
-#define fwnet_set_hdr_lf(lf)           ((lf)  << 30)
+#define fwnet_set_hdr_lf(lf)           ((lf) << 30)
 #define fwnet_set_hdr_ether_type(et)   (et)
-#define fwnet_set_hdr_dg_size(dgs)     ((dgs) << 16)
+#define fwnet_set_hdr_dg_size(dgs)     (((dgs) - 1) << 16)
 #define fwnet_set_hdr_fg_off(fgo)      (fgo)
 
 #define fwnet_set_hdr_dgl(dgl)         ((dgl) << 16)
@@ -237,18 +237,6 @@ static int fwnet_header_create(struct sk_buff *skb, struct net_device *net,
        return -net->hard_header_len;
 }
 
-static int fwnet_header_rebuild(struct sk_buff *skb)
-{
-       struct fwnet_header *h = (struct fwnet_header *)skb->data;
-
-       if (get_unaligned_be16(&h->h_proto) == ETH_P_IP)
-               return arp_find((unsigned char *)&h->h_dest, skb);
-
-       dev_notice(&skb->dev->dev, "unable to resolve type %04x addresses\n",
-                  be16_to_cpu(h->h_proto));
-       return 0;
-}
-
 static int fwnet_header_cache(const struct neighbour *neigh,
                              struct hh_cache *hh, __be16 type)
 {
@@ -282,7 +270,6 @@ static int fwnet_header_parse(const struct sk_buff *skb, unsigned char *haddr)
 
 static const struct header_ops fwnet_header_ops = {
        .create         = fwnet_header_create,
-       .rebuild        = fwnet_header_rebuild,
        .cache          = fwnet_header_cache,
        .cache_update   = fwnet_header_cache_update,
        .parse          = fwnet_header_parse,
@@ -591,6 +578,9 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
        int retval;
        u16 ether_type;
 
+       if (len <= RFC2374_UNFRAG_HDR_SIZE)
+               return 0;
+
        hdr.w0 = be32_to_cpu(buf[0]);
        lf = fwnet_get_hdr_lf(&hdr);
        if (lf == RFC2374_HDR_UNFRAG) {
@@ -615,7 +605,12 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
                return fwnet_finish_incoming_packet(net, skb, source_node_id,
                                                    is_broadcast, ether_type);
        }
+
        /* A datagram fragment has been received, now the fun begins. */
+
+       if (len <= RFC2374_FRAG_HDR_SIZE)
+               return 0;
+
        hdr.w1 = ntohl(buf[1]);
        buf += 2;
        len -= RFC2374_FRAG_HDR_SIZE;
@@ -627,7 +622,10 @@ static int fwnet_incoming_packet(struct fwnet_device *dev, __be32 *buf, int len,
                fg_off = fwnet_get_hdr_fg_off(&hdr);
        }
        datagram_label = fwnet_get_hdr_dgl(&hdr);
-       dg_size = fwnet_get_hdr_dg_size(&hdr); /* ??? + 1 */
+       dg_size = fwnet_get_hdr_dg_size(&hdr);
+
+       if (fg_off + len > dg_size)
+               return 0;
 
        spin_lock_irqsave(&dev->lock, flags);
 
@@ -735,6 +733,22 @@ static void fwnet_receive_packet(struct fw_card *card, struct fw_request *r,
        fw_send_response(card, r, rcode);
 }
 
+static int gasp_source_id(__be32 *p)
+{
+       return be32_to_cpu(p[0]) >> 16;
+}
+
+static u32 gasp_specifier_id(__be32 *p)
+{
+       return (be32_to_cpu(p[0]) & 0xffff) << 8 |
+              (be32_to_cpu(p[1]) & 0xff000000) >> 24;
+}
+
+static u32 gasp_version(__be32 *p)
+{
+       return be32_to_cpu(p[1]) & 0xffffff;
+}
+
 static void fwnet_receive_broadcast(struct fw_iso_context *context,
                u32 cycle, size_t header_length, void *header, void *data)
 {
@@ -744,9 +758,6 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
        __be32 *buf_ptr;
        int retval;
        u32 length;
-       u16 source_node_id;
-       u32 specifier_id;
-       u32 ver;
        unsigned long offset;
        unsigned long flags;
 
@@ -763,22 +774,17 @@ static void fwnet_receive_broadcast(struct fw_iso_context *context,
 
        spin_unlock_irqrestore(&dev->lock, flags);
 
-       specifier_id =    (be32_to_cpu(buf_ptr[0]) & 0xffff) << 8
-                       | (be32_to_cpu(buf_ptr[1]) & 0xff000000) >> 24;
-       ver = be32_to_cpu(buf_ptr[1]) & 0xffffff;
-       source_node_id = be32_to_cpu(buf_ptr[0]) >> 16;
-
-       if (specifier_id == IANA_SPECIFIER_ID &&
-           (ver == RFC2734_SW_VERSION
+       if (length > IEEE1394_GASP_HDR_SIZE &&
+           gasp_specifier_id(buf_ptr) == IANA_SPECIFIER_ID &&
+           (gasp_version(buf_ptr) == RFC2734_SW_VERSION
 #if IS_ENABLED(CONFIG_IPV6)
-            || ver == RFC3146_SW_VERSION
+            || gasp_version(buf_ptr) == RFC3146_SW_VERSION
 #endif
-           )) {
-               buf_ptr += 2;
-               length -= IEEE1394_GASP_HDR_SIZE;
-               fwnet_incoming_packet(dev, buf_ptr, length, source_node_id,
+           ))
+               fwnet_incoming_packet(dev, buf_ptr + 2,
+                                     length - IEEE1394_GASP_HDR_SIZE,
+                                     gasp_source_id(buf_ptr),
                                      context->card->generation, true);
-       }
 
        packet.payload_length = dev->rcv_buffer_size;
        packet.interrupt = 1;
@@ -1440,9 +1446,9 @@ static int fwnet_add_peer(struct fwnet_device *dev,
        return 0;
 }
 
-static int fwnet_probe(struct device *_dev)
+static int fwnet_probe(struct fw_unit *unit,
+                      const struct ieee1394_device_id *id)
 {
-       struct fw_unit *unit = fw_unit(_dev);
        struct fw_device *device = fw_parent_device(unit);
        struct fw_card *card = device->card;
        struct net_device *net;
@@ -1460,10 +1466,11 @@ static int fwnet_probe(struct device *_dev)
                goto have_dev;
        }
 
-       net = alloc_netdev(sizeof(*dev), "firewire%d", fwnet_init_dev);
+       net = alloc_netdev(sizeof(*dev), "firewire%d", NET_NAME_UNKNOWN,
+                          fwnet_init_dev);
        if (net == NULL) {
-               ret = -ENOMEM;
-               goto out;
+               mutex_unlock(&fwnet_device_mutex);
+               return -ENOMEM;
        }
 
        allocated_netdev = true;
@@ -1526,6 +1533,24 @@ static int fwnet_probe(struct device *_dev)
        return ret;
 }
 
+/*
+ * FIXME abort partially sent fragmented datagrams,
+ * discard partially received fragmented datagrams
+ */
+static void fwnet_update(struct fw_unit *unit)
+{
+       struct fw_device *device = fw_parent_device(unit);
+       struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
+       int generation;
+
+       generation = device->generation;
+
+       spin_lock_irq(&peer->dev->lock);
+       peer->node_id    = device->node_id;
+       peer->generation = generation;
+       spin_unlock_irq(&peer->dev->lock);
+}
+
 static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
 {
        struct fwnet_partial_datagram *pd, *pd_next;
@@ -1542,9 +1567,9 @@ static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev)
        kfree(peer);
 }
 
-static int fwnet_remove(struct device *_dev)
+static void fwnet_remove(struct fw_unit *unit)
 {
-       struct fwnet_peer *peer = dev_get_drvdata(_dev);
+       struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
        struct fwnet_device *dev = peer->dev;
        struct net_device *net;
        int i;
@@ -1569,26 +1594,6 @@ static int fwnet_remove(struct device *_dev)
        }
 
        mutex_unlock(&fwnet_device_mutex);
-
-       return 0;
-}
-
-/*
- * FIXME abort partially sent fragmented datagrams,
- * discard partially received fragmented datagrams
- */
-static void fwnet_update(struct fw_unit *unit)
-{
-       struct fw_device *device = fw_parent_device(unit);
-       struct fwnet_peer *peer = dev_get_drvdata(&unit->device);
-       int generation;
-
-       generation = device->generation;
-
-       spin_lock_irq(&peer->dev->lock);
-       peer->node_id    = device->node_id;
-       peer->generation = generation;
-       spin_unlock_irq(&peer->dev->lock);
 }
 
 static const struct ieee1394_device_id fwnet_id_table[] = {
@@ -1614,10 +1619,10 @@ static struct fw_driver fwnet_driver = {
                .owner  = THIS_MODULE,
                .name   = KBUILD_MODNAME,
                .bus    = &fw_bus_type,
-               .probe  = fwnet_probe,
-               .remove = fwnet_remove,
        },
+       .probe    = fwnet_probe,
        .update   = fwnet_update,
+       .remove   = fwnet_remove,
        .id_table = fwnet_id_table,
 };