--- zzzz-none-000/linux-2.6.28.10/drivers/net/ppp_generic.c 2009-05-02 18:54:43.000000000 +0000 +++ fusiv-7390-686/linux-2.6.28.10/drivers/net/ppp_generic.c 2012-02-14 14:37:49.000000000 +0000 @@ -48,6 +48,11 @@ #include #include +#if defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) +#include +struct ppp_channel *getPPPChannel(struct net_device *net_dev); +#endif + #define PPP_VERSION "2.4.2" /* @@ -470,6 +475,26 @@ goto out; } +#if defined(CONFIG_MACH_FUSIV) +#if defined(CONFIG_FUSIV_VX185) + // 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 +#define IPQOS_HOQ_PACKET 0x80 + skb->apFlowData.controlFlags |= IPQOS_HOQ_PACKET; +#endif +#if defined(CONFIG_FUSIV_VX180) || defined(CONFIG_FUSIV_VX160) + // This will prioritize the PPP LCP packets when QoS is enabled. +#if defined(CONFIG_FUSIV_KERNEL_IPQOS_TC_MARKING) +#if CONFIG_FUSIV_KERNEL_IPQOS_APQOS + skb->apFlowData.qosInfo.qos_priority = 1; +#else + skb->qosInfo.qos_priority = 1; +#endif +#endif +#endif +#endif skb_queue_tail(&pf->xq, skb); switch (pf->kind) { @@ -1560,6 +1585,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 @@ -1632,6 +1660,15 @@ ++ppp->dev->stats.rx_packets; ppp->dev->stats.rx_bytes += skb->len - 2; +#if defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) + encap = skb->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) { /* control or unknown frame - pass it to pppd */ @@ -1678,6 +1715,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; @@ -2799,11 +2843,180 @@ *pmap = NULL; } + +#if CONFIG_ATM +#if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE) +extern int isPPPModTypePPPoA(struct ppp_channel *); +#endif +#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_MACH_FUSIV) && defined(CONFIG_ATM) +struct ppp_channel *getPPPChannel(struct net_device *net_dev) +{ + struct list_head *list; + struct ppp *ppp; + ppp = (struct ppp *) net_dev->priv; + 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 = (struct ppp *) pDev->priv; + + 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 = (struct ppp *) pDev->priv; + + 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; +} + + + + /* Module/initialization stuff */ module_init(ppp_init); module_exit(ppp_cleanup); +#if defined(CONFIG_MACH_FUSIV) && defined(CONFIG_ATM) +EXPORT_SYMBOL(getPPPChannel); +#endif + +EXPORT_SYMBOL(getPhysicalIfName); +EXPORT_SYMBOL(getSessIdAndAddr); EXPORT_SYMBOL(ppp_register_channel); EXPORT_SYMBOL(ppp_unregister_channel); EXPORT_SYMBOL(ppp_channel_index);