--- zzzz-none-000/linux-4.1.38/drivers/net/usb/usbnet.c 2017-01-18 18:48:06.000000000 +0000 +++ bcm63-7582-715/linux-4.1.38/drivers/net/usb/usbnet.c 2020-11-25 10:06:48.000000000 +0000 @@ -46,6 +46,11 @@ #include #include +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM_USBNET_ACCELERATION) && defined(CONFIG_BLOG)) +#include +#include +#endif + #define DRIVER_VERSION "22-Aug-2005" @@ -323,6 +328,30 @@ return; } +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM_USBNET_ACCELERATION) && defined(CONFIG_BLOG)) + if(skb->clone_fc_head == NULL) + { + /* Make sure fcache does not expand the skb->data if clone_fc_head + * is not set by the dongle driver's(ex:rndis_host.c, asix.c etc..) + * we expect dongle/class drivers using fcache to set minumun headroom + * available for all packets in an aggregated skb by calling + * skb_clone_headers_set() before calling usbnet_skb_return. + * + * Ex:rndis based drivers have 8 bytes spacig between 2 packets in an + * aggreated skb. we can call skb_clone_ headers_set(skb, 8) in + * rndis_rx_fixup(); + * By setting this we are telling fcache or enet driver can expand + * skb->data for upto 8 bytes. This is helpful to avoid packet + * copy incase of LAN VLAN's, External Switch tag's etc.. + * + */ + skb_clone_headers_set(skb, 0); + } + if (PKT_DONE == blog_sinit(skb, skb->dev, TYPE_ETH, 0, BLOG_USBPHY)) { + return; + } +#endif + skb->protocol = eth_type_trans (skb, dev->net); dev->net->stats.rx_packets++; dev->net->stats.rx_bytes += skb->len; @@ -334,7 +363,11 @@ if (skb_defer_rx_timestamp(skb)) return; +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM_USBNET_ACCELERATION) && defined(CONFIG_BLOG)) + status = netif_receive_skb(skb); +#else status = netif_rx (skb); +#endif if (status != NET_RX_SUCCESS) netif_dbg(dev, rx_err, dev->net, "netif_rx status %d\n", status); @@ -454,6 +487,10 @@ } EXPORT_SYMBOL_GPL(usbnet_defer_kevent); +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM96838)) +int bcm_usb_hw_align_size = 1024; +#endif + /*-------------------------------------------------------------------------*/ static void rx_complete (struct urb *urb); @@ -472,7 +509,12 @@ return -ENOLINK; } +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM96838)) + skb = __netdev_alloc_skb_ip_align(dev->net, size + bcm_usb_hw_align_size, flags); +#else skb = __netdev_alloc_skb_ip_align(dev->net, size, flags); +#endif + if (!skb) { netif_dbg(dev, rx_err, dev->net, "no rx skb\n"); usbnet_defer_kevent (dev, EVENT_RX_MEMORY); @@ -480,6 +522,14 @@ return -ENOMEM; } +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM96838)) + { + unsigned int aligned_len = (unsigned int)skb->data; + aligned_len = bcm_usb_hw_align_size - (aligned_len & (bcm_usb_hw_align_size - 1)); + skb_reserve(skb, aligned_len); + } +#endif + entry = (struct skb_data *) skb->cb; entry->urb = urb; entry->dev = dev; @@ -1293,6 +1343,21 @@ unsigned long flags; int retval; +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM_USBNET_ACCELERATION) && defined(CONFIG_BLOG)) + if(skb) + { + struct sk_buff *orig_skb = skb; + skb = nbuff_xlate((pNBuff_t )skb); + if (skb == NULL) + { + dev->net->stats.tx_dropped++; + nbuff_free((pNBuff_t) orig_skb); + return NETDEV_TX_OK; + } + blog_emit( skb, net, TYPE_ETH, 0, BLOG_USBPHY ); + } +#endif + if (skb) skb_tx_timestamp(skb); @@ -1309,6 +1374,33 @@ } } +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM963268)) + /* on 63268 if TX buffer is not 4 byte aligned then some times + * USB descriptors are corrupted beacuse of a BUG in hW + * for unaligned buffers copy data to a new aligned buffer + */ + if (((unsigned int)skb->data & 0x3) ) { + struct sk_buff *oskb = skb; + int newheadroom = skb_headroom(oskb); + /* create a new skb from an existing skb + * and adjust the data pointer to be word aligned + */ + newheadroom += newheadroom%4; + skb = skb_copy_expand(oskb, newheadroom, 1, GFP_ATOMIC); + dev_kfree_skb_any(oskb); + + if ( unlikely(!skb) ) + goto drop; + + if (unlikely((unsigned int)skb->data & 0x3)) + { + printk(KERN_WARNING"%s: unaligned skb->data=%p \n", __func__, + skb->data); + goto drop; + } + } +#endif + if (!(urb = usb_alloc_urb (0, GFP_ATOMIC))) { netif_dbg(dev, tx_err, dev->net, "no urb\n"); goto drop; @@ -1655,6 +1747,9 @@ net->watchdog_timeo = TX_TIMEOUT_JIFFIES; net->ethtool_ops = &usbnet_ethtool_ops; +#if (defined(CONFIG_BCM_KF_USBNET) && defined(CONFIG_BCM96838)) + printk("+++++ &bcm_usb_hw_align_size =%p \n", &bcm_usb_hw_align_size); +#endif // allow device-specific bind/init procedures // NOTE net->name still not usable ... if (info->bind) { @@ -1662,6 +1757,8 @@ if (status < 0) goto out1; +/*--- 20160222 AVM/VGJ - CHANGESET: AVM-TWEAK: we always want usb0, not eth4 ---*/ +#if 0 // heuristic: "usb%d" for links we know are two-host, // else "eth%d" when there's reasonable doubt. userspace // can rename the link if it knows better. @@ -1669,6 +1766,8 @@ ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || (net->dev_addr [0] & 0x02) == 0)) strcpy (net->name, "eth%d"); +#endif + /* WLAN devices should always be named "wlan%d" */ if ((dev->driver_info->flags & FLAG_WLAN) != 0) strcpy(net->name, "wlan%d");