--- zzzz-none-000/linux-3.10.107/drivers/net/ppp/ppp_generic.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/drivers/net/ppp/ppp_generic.c 2021-11-10 11:53:55.000000000 +0000 @@ -22,6 +22,12 @@ * ==FILEVERSION 20041108== */ +/** + * Some part of this file is modified by Ikanos Communications. + * + * Copyright (C) 2013-2014 Ikanos Communications. + */ + #include #include #include @@ -56,6 +62,23 @@ #define PPP_VERSION "2.4.2" +#if defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) +#include "atm/atmencap.h" + +struct ppp_channel *getPPPChannel(struct net_device *net_dev); +#endif + + +#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE) +extern int isPPPModTypePPPoE(struct ppp_channel *); +extern char *getPPPoEIfName(struct ppp_channel *); +extern int getPPPoESessIdAndAddr(struct ppp_channel *, unsigned char *); +#endif + +#if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE) +extern int isPPPModTypePPPoA(struct ppp_channel *pppchan); +#endif + /* * Network protocols we support. */ @@ -493,6 +516,15 @@ goto out; } +#if defined(CONFIG_MACH_FUSIV) + // This information is used by the ATM/Ethernet/VDSL drivers + // to decide whether this packet should be enqueued at the + // head of the ipqos queues. This is done to prioritize + // PPP control packet over other packets +#if defined(CONFIG_FUSIV_KERNEL_AP_2_AP) || defined(CONFIG_FUSIV_KERNEL_AP_2_AP_MODULE) + skb->apFlowData.controlFlags |= IPQOS_HOQ_PACKET; +#endif +#endif skb_queue_tail(&pf->xq, skb); switch (pf->kind) { @@ -1718,6 +1750,9 @@ struct sk_buff *ns; int proto, len, npi; +#if defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) + unsigned char encap; +#endif /* * Decompress the frame, if compressed. * Note that some decompressors need to see uncompressed frames @@ -1791,6 +1826,14 @@ ++ppp->stats64.rx_packets; ppp->stats64.rx_bytes += skb->len - 2; +#if defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) + encap = skb->apFlowData.encap; + + if ((encap == ENCAPIDROUTEDLLCPPPOA) || (encap == ENCAPIDROUTEDVCPPPOA)) + proto = PPP_IP; + if ((encap == ENCAPIDROUTEDLLCPPPOA_IPV6) || (encap == ENCAPIDROUTEDVCPPPOA_IPV6)) + proto = PPP_IPV6; +#endif npi = proto_to_npindex(proto); if (npi < 0) { @@ -1836,6 +1879,13 @@ ppp->npmode[npi] != NPMODE_PASS) { kfree_skb(skb); } else { + +#if defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) + /* in this case; PPP 2 bytes are already chopped off, as pkt is ip/ipv6 */ + if((encap != ENCAPIDROUTEDLLCPPPOA) && + (encap != ENCAPIDROUTEDVCPPPOA)&& (encap != ENCAPIDROUTEDLLCPPPOA_IPV6) + && (encap != ENCAPIDROUTEDVCPPPOA_IPV6)) +#endif /* chop off protocol */ skb_pull_rcsum(skb, 2); skb->dev = ppp->dev; @@ -2983,11 +3033,171 @@ return idr_find(p, n); } +// AVM/TKL: MERGE split defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) +#if defined(CONFIG_MACH_FUSIV) +#if defined(CONFIG_ATM) +struct ppp_channel *getPPPChannel(struct net_device *net_dev) +{ + struct list_head *list; + struct ppp *ppp; + ppp = (struct ppp *) netdev_priv(net_dev); + list = &ppp->channels; + + if (!list_empty(list)) + { + struct ppp_channel *pppchan; + struct channel *pch; + + list = list->next; + + pch = list_entry(list, struct channel, clist); + + if (!pch) + return NULL; + + pppchan = pch->chan; + + if (!pppchan) + return NULL; + + return pppchan; + } + + return NULL; +} +#endif + +char *getPhysicalIfName(char *pIfName) +{ + struct net_device *pDev; + struct list_head *list; + struct ppp *ppp; + + if (!pIfName) + return NULL; + + pDev = dev_get_by_name(&init_net, pIfName); + + if (!pDev) + return NULL; + + ppp = netdev_priv(pDev); + + dev_put(pDev); + + if (!ppp) + return NULL; + + list = &ppp->channels; + + if (!list_empty(list)) + { + struct ppp_channel *pppchan; + struct channel *pch; + + list = list->next; + + pch = list_entry(list, struct channel, clist); + + if (!pch) + return NULL; + + pppchan = pch->chan; + + if (!pppchan) + return NULL; + + if ((pppchan->ops) && (pppchan->ops->start_xmit)) + { +#if CONFIG_ATM +#if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE) + if (isPPPModTypePPPoA(pppchan)) + return "atm"; +#endif +#endif + +#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE) + if (isPPPModTypePPPoE(pppchan)) + return (getPPPoEIfName(pppchan)); +#endif + } + } + + printk("getPhysicalIfName: FAILED..\r\n"); + + return NULL; +} + +int getSessIdAndAddr(char *pIfName, unsigned char *addr) +{ + struct net_device *pDev; + struct list_head *list; + struct ppp *ppp; + + if (!pIfName) + return 0; + + pDev = dev_get_by_name(&init_net, pIfName); + + if (!pDev) + return 0; + + + ppp = netdev_priv(pDev); + + dev_put(pDev); + + if (!ppp) + return 0; + + list = &ppp->channels; + + if (!list_empty(list)) + { + struct ppp_channel *pppchan; + struct channel *pch; + + list = list->next; + + pch = list_entry(list, struct channel, clist); + + if (!pch) + return 0; + + pppchan = pch->chan; + + if (!pppchan) + return 0; + + if ((pppchan->ops) && (pppchan->ops->start_xmit)) + { +#if defined(CONFIG_PPPOE) || defined(CONFIG_PPPOE_MODULE) + if (isPPPModTypePPPoE(pppchan)) + return (getPPPoESessIdAndAddr(pppchan, addr)); +#endif + } + } + + printk("getSessIdAndAddr: FAILED..\r\n"); + + return 0; +} +#endif // CONFIG_MACH_FUSIV + /* Module/initialization stuff */ module_init(ppp_init); module_exit(ppp_cleanup); +// AVM/TKL: MERGE split defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) +#if defined(CONFIG_MACH_FUSIV) +#if defined(CONFIG_ATM) +EXPORT_SYMBOL(getPPPChannel); +#endif +EXPORT_SYMBOL(getPhysicalIfName); +EXPORT_SYMBOL(getSessIdAndAddr); +#endif + EXPORT_SYMBOL(ppp_register_net_channel); EXPORT_SYMBOL(ppp_register_channel); EXPORT_SYMBOL(ppp_unregister_channel);