[Feature][T106_eSDK]update from T106-V2.01.01.02P56U09.AP.17.09_CAP.17.09.01 to T106-M42-PLXXXX-P56U11.AP.19.00_CAP.19.00.01 -- code

Only Configure: No
Affected branch: master
Affected module: unknow
Is it affected on both ZXIC and MTK: only ZXIC
Self-test: Yes
Doc Update: No

Change-Id: I5eb7f586f78a987785b0f9885f1300c42bfd6819
diff --git a/upstream/linux-5.10/drivers/net/ethernet/zte/zx29_gmac.c b/upstream/linux-5.10/drivers/net/ethernet/zte/zx29_gmac.c
index 668d9d9..32cb5a5 100755
--- a/upstream/linux-5.10/drivers/net/ethernet/zte/zx29_gmac.c
+++ b/upstream/linux-5.10/drivers/net/ethernet/zte/zx29_gmac.c
@@ -25,8 +25,11 @@
 #include <linux/gpio.h>

 #include <linux/of_gpio.h>

 #include <linux/device.h>

+#include <uapi/linux/sched/types.h>

 #include "zx29_gmac.h"

 

+#define GMAC_RX_WORKER_TH 1

+

 #define gmac_printk(_format, _args...)		do{printk(KERN_INFO"gmac," _format "\n",##_args);}while(0)

 

 static u8 zx29_gmac_addr[MAC_ADDR_LENTH] = {0xec,0x1d,0x7f,0xb0,0x2f,0x32};

@@ -86,10 +89,11 @@
 

 	d = (struct bd_tx *)priv->dma_tx_vir;

 

+      

 	if (n == priv->tx_bd_offset) 

 		return 0;

 

-	if (d[n].TDES0 & DMA_OWNER)

+	if ( (!d) || (d[n].TDES0 & DMA_OWNER))

 		return 0;

 

 	if (d[n].skb == NULL)

@@ -123,7 +127,7 @@
     int   n						= prv->rx_bd_offset;

     struct bd_rx *d				= (struct bd_rx*)prv->dma_rx_vir;

 

-    if(d[n].RDES0 & DMA_OWNER) 

+    if ((!d) || (d[n].RDES0 & DMA_OWNER)) 

     {

         return 0;

     }

@@ -359,6 +363,56 @@
 	return (exhausted > 10);

 }

 

+#ifdef GMAC_RX_WORKER_TH

+static struct task_struct *s_gmac_rx_worker = 0;

+static int ko_remove_flag = 0;

+struct semaphore s_gmac_rx_sem = {0};

+static int gmac_rx_worker(void *dev)

+{

+	struct net_device *ndev = (struct net_device *)dev;

+	struct zx29_gmac_dev *prv = (struct zx29_gmac_dev *)netdev_priv(ndev);

+	volatile unsigned *gmac = (unsigned *)ndev->base_addr;

+	unsigned int events = prv->int_event;

+

+	do {

+		down(&s_gmac_rx_sem);

+		if (ko_remove_flag)

+		    return 0;

+		events = prv->int_event;

+    	do {

+    		if (events & INT_ST_TX)

+    			zx29_gmac_tx(ndev);

+    

+    		if (events & INT_ST_RX)

+    			zx29_gmac_rx(ndev);

+    

+    		events = MAC(0x1014);

+    		MAC(0x1014) = events;

+    	} while (events & (INT_ST_TX | INT_ST_RX));

+    

+    #ifndef GMAC_NO_INT

+    	mac_int_enable();

+    #endif

+	} while(1);

+

+	return 0;

+}

+

+static int zx29_gmac_worker(struct net_device* pnetdev)

+{

+    struct sched_param param = {.sched_priority = 40};

+

+	sema_init(&s_gmac_rx_sem, 0);

+

+	s_gmac_rx_worker = kthread_create(gmac_rx_worker, (void *)pnetdev, "gmac_rx_worker");

+

+	//sched_setscheduler(s_gmac_rx_worker, SCHED_RR, &param);

+    wake_up_process(s_gmac_rx_worker);

+

+	return 0;

+}

+

+#endif

 

 #ifndef GMAC_NO_INT

 static irqreturn_t zx29_gmac_interrupt(int irq, void *dev_id)

@@ -371,8 +425,11 @@
 	MAC(0x1014) = priv->int_event;

 

 	mac_int_disable();

+#ifndef GMAC_RX_WORKER_TH

 	tasklet_schedule(&priv->tasklet);

-

+#else

+	up(&s_gmac_rx_sem);

+#endif

 	return IRQ_HANDLED;

 }

 

@@ -424,7 +481,11 @@
 	ktime_t gmac_schdule_time = ktime_set(0, delay_in_us * 1000);

 	

 	hrtimer_forward_now(timer, gmac_schdule_time);

+#ifndef GMAC_RX_WORKER_TH

 	tasklet_schedule(g_gmac_tasklet);

+#else

+    up(&s_gmac_rx_sem);

+#endif

 	return HRTIMER_RESTART;

 }

 #endif

@@ -759,7 +820,7 @@
 		return ret;

 	}

 

-	netif_carrier_on(ndev);

+//	netif_carrier_on(ndev);

 	spin_unlock_irqrestore(&priv->lock, flags);

 	

 	phy_start(priv->phydev);

@@ -1725,12 +1786,46 @@
 

 /*zw.wang add for switching the primary/secondary mode of gmac on 20240118 end */

 

+/*zw.wang add a new interface to obtain the PHY link status on 20250226 begin*/

+ssize_t phy_pma_link_show(struct device *dev, struct device_attribute *attr,

+			  char *buf)

+{

+	int val = 0;

+	struct platform_device *pdev = to_platform_device(dev);

+	if (!pdev) {

+		printk(KERN_ERR "%s : %s pdev : %x \n", __func__, __LINE__,

+		       pdev);

+		return -1;

+	}

+	struct net_device *ndev = platform_get_drvdata(pdev);

+	if (!ndev) {

+		printk(KERN_ERR "%s : %s ndev : %x \n", __func__, __LINE__,

+		       ndev);

+		return -1;

+	}

+	struct zx29_gmac_dev *priv = (struct zx29_gmac_dev *)netdev_priv(ndev);

+	if (!priv) {

+		printk(KERN_ERR "%s : %s priv : %x \n", __func__, __LINE__,

+		       priv);

+		return -1;

+	}

+	mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d,0x1);

+	mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0e,0x1);

+	mdiobus_write(priv->phydev->mdio.bus, priv->phydev->mdio.addr, 0x0d,0x4000 | 0x1);

+	val = mdiobus_read(priv->phydev->mdio.bus, priv->phydev->mdio.addr,0x0e);

+	sprintf(buf, "link : %s\n", (val & BIT(2)) ? "yes":"no");

+	return strlen(buf);

+}

+

+/*zw.wang add a new interface to obtain the PHY link status on 20250226 end*/

+

 static DEVICE_ATTR(gmac_test, 0664, show_fun, store_fun);

 static DEVICE_ATTR(mdio_test, 0664, mdio_show, mdio_store);

 static DEVICE_ATTR(free_mdio, 0664, free_mdio_show, free_mdio_store);

 static DEVICE_ATTR(debug_on, 0664, debug_on_show, debug_on_store);

 static DEVICE_ATTR(gmac_power, 0664, gmac_power_show, gmac_power_store);//jb.qi add for gamc power down on 20231116

 static DEVICE_ATTR(gmac_master_or_slave, 0664, gmac_master_or_slave_show, gmac_master_or_slave_store);//zw.wang add for switching the primary/secondary mode of gmac on 20240118

+static DEVICE_ATTR_RO(phy_pma_link); //zw.wang add a new interface to obtain the PHY link status on 20250226

 

 static int zx29_gmac_probe(struct platform_device *pdev)

 {

@@ -1759,6 +1854,7 @@
 	device_create_file(&pdev->dev, &dev_attr_debug_on);

     device_create_file(&pdev->dev, &dev_attr_gmac_power);//jb.qi add for gamc power down on 20231116

 	device_create_file(&pdev->dev, &dev_attr_gmac_master_or_slave);//zw.wang add for switching the primary/secondary mode of gmac on 20240118

+	device_create_file(&pdev->dev, &dev_attr_phy_pma_link); //zw.wang add a new interface to obtain the PHY link status on 20250226

 

 	prv = netdev_priv(ndev);

 	memset(prv, 0, sizeof(*prv));

@@ -1851,6 +1947,10 @@
 		goto errdev;

 	}

 

+#ifdef GMAC_RX_WORKER_TH

+	zx29_gmac_worker(ndev);//gmac_rx_worker

+#endif

+

 	of_property_read_u32(np, "port-nums", &prv->nports); 

 	of_property_read_u32(np, "rmii-ports", &prv->rmii_port);

 	prv->base_addr = ndev->base_addr;

@@ -1987,9 +2087,10 @@
 

 //	    gpio_direction_output(priv->gpio_power[0], 1);

 //	    msleep(500);

-		unregister_netdev(ndev);

+//		unregister_netdev(ndev);

 

 		phy_disconnect(priv->phydev);

+		unregister_netdev(ndev);

 			

 	    kobj_gmac_del(NULL);

 		

@@ -1998,11 +2099,17 @@
 #ifndef GMAC_NO_INT

 		free_irq(ndev->irq, ndev);

 #endif

+		

+#ifdef GMAC_RX_WORKER_TH

+	        ko_remove_flag = 1;

+                up(&s_gmac_rx_sem);	

+#endif 

+

 		tasklet_disable(&priv->tasklet);

 		tasklet_kill(&priv->tasklet);

 

-		if (priv->dma_rx_vir)

-			dma_free_coherent(ndev->dev.parent, GMAC_BUF_LEN, priv->dma_rx_vir, priv->dma_rx_phy);

+		if (priv->dma_rx_vir_init)

+			dma_free_coherent(ndev->dev.parent, GMAC_BUF_LEN, priv->dma_rx_vir_init, priv->dma_rx_phy_init);

 

 		pm_relax(&pdev->dev);

 		free_netdev(ndev);

@@ -2020,6 +2127,7 @@
 	    device_remove_file(&pdev->dev, &dev_attr_debug_on);

         device_remove_file(&pdev->dev, &dev_attr_gmac_power);//jb.qi add for gamc power down on 20231116

 		device_remove_file(&pdev->dev, &dev_attr_gmac_master_or_slave);//zw.wang add for switching the primary/secondary mode of gmac on 20240118

+		device_remove_file(&pdev->dev, &dev_attr_phy_pma_link); //zw.wang add a new interface to obtain the PHY link status on 20250226

 	}

 	return 0;

 }

diff --git a/upstream/linux-5.10/drivers/net/ethernet/zte/zx29_gmac_event.c b/upstream/linux-5.10/drivers/net/ethernet/zte/zx29_gmac_event.c
index 750580b..6df9cfd 100755
--- a/upstream/linux-5.10/drivers/net/ethernet/zte/zx29_gmac_event.c
+++ b/upstream/linux-5.10/drivers/net/ethernet/zte/zx29_gmac_event.c
@@ -137,7 +137,7 @@
 

 void kobj_gmac_del(struct kobject *kobject)

 {

-	kset_unregister(kset_gmac);

+//	kset_unregister(kset_gmac);

 	

     kobject_uevent(typekobj, KOBJ_REMOVE);

 	kobject_del(typekobj);

@@ -150,6 +150,7 @@
 

 	kfree(gmackobj);

 	

+	kset_unregister(kset_gmac);

 	printk("[gmac kobj_test: delete!]\n");

 }

 EXPORT_SYMBOL(kobj_gmac_del);

@@ -278,8 +279,8 @@
 	}

 	kset_gmac = kset_create_and_add("gmac", &gmac_uevent_ops, NULL); 

 	kobject_init(gmackobj, &gmacktype);

-	kobject_add(gmackobj,&kset_gmac->kobj,"%s","gmacconfig");  

 	gmackobj->kset = kset_gmac;

+	kobject_add(gmackobj,&kset_gmac->kobj,"%s","gmacconfig");  

 

 	typekobj = kzalloc(sizeof(*typekobj),GFP_KERNEL);

 	if(!typekobj){

@@ -288,8 +289,8 @@
 	}

 //	kset_gmac = kset_create_and_add("gmac", &gmac_uevent_ops, NULL); 

 	kobject_init(typekobj, &typektype);

-	kobject_add(typekobj,&kset_gmac->kobj,"%s",name);  

 	typekobj->kset = kset_gmac;

+	kobject_add(typekobj,&kset_gmac->kobj,"%s",name);  

 

 	strcpy(type, name);

 	

diff --git a/upstream/linux-5.10/drivers/net/phy/phy_device.c b/upstream/linux-5.10/drivers/net/phy/phy_device.c
index d9b53ba..f6a5a56 100755
--- a/upstream/linux-5.10/drivers/net/phy/phy_device.c
+++ b/upstream/linux-5.10/drivers/net/phy/phy_device.c
@@ -1316,6 +1316,10 @@
 }
 EXPORT_SYMBOL(phy_sfp_probe);
 
+static bool phy_drv_supports_irq(struct phy_driver *phydrv)
+{
+	return phydrv->config_intr && phydrv->ack_interrupt;
+}
 /**
  * phy_attach_direct - attach a network device to a given PHY device pointer
  * @dev: network device to attach
@@ -1421,6 +1425,8 @@
 
 	phydev->state = PHY_READY;
 
+	if (!phy_drv_supports_irq(phydev->drv) && phy_interrupt_is_valid(phydev))
+		phydev->irq = PHY_POLL;
 	/* Port is set to PORT_TP by default and the actual PHY driver will set
 	 * it to different value depending on the PHY configuration. If we have
 	 * the generic PHY driver we can't figure it out, thus set the old
@@ -2819,7 +2825,7 @@
 	if (delay < 0)
 		return delay;
 
-	if (delay && size == 0)
+	if (size == 0)
 		return delay;
 
 	if (delay < delay_values[0] || delay > delay_values[size - 1]) {
@@ -2852,10 +2858,6 @@
 }
 EXPORT_SYMBOL(phy_get_internal_delay);
 
-static bool phy_drv_supports_irq(struct phy_driver *phydrv)
-{
-	return phydrv->config_intr && phydrv->ack_interrupt;
-}
 
 /**
  * phy_probe - probe and init a PHY device
diff --git a/upstream/linux-5.10/drivers/net/zvnet/zvnet_dev.c b/upstream/linux-5.10/drivers/net/zvnet/zvnet_dev.c
index c7da7a4..ffade7e 100755
--- a/upstream/linux-5.10/drivers/net/zvnet/zvnet_dev.c
+++ b/upstream/linux-5.10/drivers/net/zvnet/zvnet_dev.c
@@ -9,6 +9,8 @@
 #include "ram_config.h"

 #include <net/netfilter/nf_conntrack.h>

 #include <net/SI/fast_common.h>

+#include <pub_debug_info.h>

+

 /*******************************************************************************

  *                             Macro definitions                               *

  ******************************************************************************/

@@ -50,6 +52,18 @@
 	unsigned short flag;

 	struct	T_zvnet_pkt_stats pkt[2];

 };

+struct zvnet_arphdr {

+	unsigned short		ar_hrd;		/* format of hardware address	*/

+	unsigned short		ar_pro;		/* format of protocol address	*/

+	unsigned char		ar_hln;		/* length of hardware address	*/

+	unsigned char		ar_pln;		/* length of protocol address	*/

+	unsigned short		ar_op;		/* ARP opcode (command)		*/

+	unsigned char		ar_sha[ETH_ALEN];	/* sender hardware address	*/

+	unsigned char		ar_sip[4];		/* sender IP address		*/

+	unsigned char		ar_tha[ETH_ALEN];	/* target hardware address	*/

+	unsigned char		ar_tip[4];		/* target IP address		*/

+};

+

 /*******************************************************************************

  *						   Local variable definitions					*

  ******************************************************************************/

@@ -65,6 +79,7 @@
 struct semaphore g_zvnet_free_sem;

 struct semaphore g_zvnet_xmit_sem;

 struct sk_buff_head g_zvnet_skb_xmit_queue;

+atomic_t g_zvnet_pm_flag;

 

 unsigned int g_wrap_packet_size = 1000;

 module_param(g_wrap_packet_size, int, 0644);

@@ -152,7 +167,7 @@
     unsigned char *p = data;

     for(i = 0; i < len && i < limit_len; i+=16)

     {

-        printk("0x%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",i,

+        printk("0x%04x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",i,

             p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],

             p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);

         p += 16;

@@ -160,6 +175,11 @@
 }

 /* Ended by AICoder, pid:z5702yf8bad07ad1448a083e806dc31250b2418f */

 

+void zvnet_set_pm_flag(unsigned int flag){

+	if(flag & 0x100000)

+		atomic_set(&g_zvnet_pm_flag, 1);

+}

+

 int zvnet_get_index_by_netdev(struct net_device *net)

 {

     int i;

@@ -304,11 +324,127 @@
 	/* make sure we initialize shinfo sequentially */

 	skb_reset_network_header(skb);

 	skb_set_kcov_handle(skb, kcov_common_handle());

-	if(unlikely(g_trace_limit > 0)){

-		printk("-%s-dump_packet-start-%d\n", skb->dev->name, skb->len);

+	if(unlikely(g_trace_limit & 1)){

+		printk("-%s-dump_fromap-start-%d\n", skb->dev->name, skb->len);

 		zvnet_dump_packet(skb->data, skb->len, g_trace_limit);

-		printk("-%s-dump_packet-end-\n", skb->dev->name);

+		printk("-%s-dump_fromap-end-\n", skb->dev->name);

 	}

+/* Started by AICoder, pid:j2d34uccf7y1f37146a108290182771184940711 */

+	if (atomic_read(&g_zvnet_pm_flag)) {

+		unsigned short l2_hdr_len = 0;

+		unsigned short h_proto = htons(*(unsigned short *)(skb->data + ETH_ALEN + ETH_ALEN));

+		again:

+		if (l2_hdr_len + ETH_HLEN < skb->len) {

+			switch (h_proto) {

+				case ETH_P_IP: {

+					struct iphdr *iph = (struct iphdr *)(skb->data + ETH_HLEN + l2_hdr_len);

+					if (iph->protocol == IPPROTO_TCP) {

+						struct tcphdr *tcph = (struct tcphdr *)(((unsigned char *)iph) + iph->ihl * 4);

+						char *flag;

+						if (tcph->ack) {

+							if (tcph->fin)

+								flag = "FA";

+							else if (tcph->syn)

+								flag = "SA";

+							else if (tcph->psh)

+								flag = "PA";

+							else

+								flag = "A";

+						} else {

+							if (tcph->fin)

+								flag = "F";

+							else if (tcph->syn)

+								flag = "S";

+							else if (tcph->rst)

+								flag = "R";

+							else

+								flag = "";

+						}

+						sc_debug_info_record("cap_net", "%u-%pI4-%pI4-%u%s %u:%u/%u\n",

+											pbuf_temp->dev, &iph->saddr, &iph->daddr,

+											iph->protocol, flag, ntohs(tcph->source), ntohs(tcph->dest), skb->len);

+					} else if (iph->protocol == IPPROTO_UDP) {

+						struct udphdr *udph = (struct udphdr *)(((unsigned char *)iph) + iph->ihl * 4);

+						sc_debug_info_record("cap_net", "%u-%pI4-%pI4-%u %u:%u/%u\n",

+											pbuf_temp->dev, &iph->saddr, &iph->daddr,

+											iph->protocol, ntohs(udph->source), ntohs(udph->dest), skb->len);

+					} else if (iph->protocol == IPPROTO_ICMP) {

+						struct icmphdr *icmph = (struct icmphdr *)(((unsigned char *)iph) + iph->ihl * 4);

+						sc_debug_info_record("cap_net", "%u-%pI4-%pI4-%u %u:%u/%u\n",

+											pbuf_temp->dev, &iph->saddr, &iph->daddr,

+											iph->protocol, icmph->type, icmph->code, skb->len);

+					} else {

+						sc_debug_info_record("cap_net", "%u-%pI4-%pI4-%u/%u\n",

+											pbuf_temp->dev, &iph->saddr, &iph->daddr,

+											iph->protocol, skb->len);

+					}

+					break;

+				}

+				case ETH_P_IPV6: {

+					struct ipv6hdr *iph = (struct ipv6hdr *)(skb->data + ETH_HLEN + l2_hdr_len);

+					if (iph->nexthdr == NEXTHDR_TCP) {

+						struct tcphdr *tcph = (struct tcphdr *)(((unsigned char *)iph) + sizeof(struct ipv6hdr));

+						char *flag;

+						if (tcph->ack) {

+							if (tcph->fin)

+								flag = "FA";

+							else if (tcph->syn)

+								flag = "SA";

+							else if (tcph->psh)

+								flag = "PA";

+							else

+								flag = "A";

+						} else {

+							if (tcph->fin)

+								flag = "F";

+							else if (tcph->syn)

+								flag = "S";

+							else if (tcph->rst)

+								flag = "R";

+							else

+								flag = "";

+						}

+						sc_debug_info_record("cap_net", "%u-%pI6-%pI6-%u%s %u:%u/%u\n",

+											pbuf_temp->dev, iph->saddr.s6_addr32, iph->daddr.s6_addr32,

+											iph->nexthdr, flag, ntohs(tcph->source), ntohs(tcph->dest), skb->len);

+					} else if (iph->nexthdr == NEXTHDR_UDP) {

+						struct udphdr *udph = (struct udphdr *)(((unsigned char *)iph) + sizeof(struct ipv6hdr));

+						sc_debug_info_record("cap_net", "%u-%pI6-%pI6-%u %u:%u/%u\n",

+											pbuf_temp->dev, iph->saddr.s6_addr32, iph->daddr.s6_addr32,

+											iph->nexthdr, ntohs(udph->source), ntohs(udph->dest), skb->len);

+					} else if (iph->nexthdr == NEXTHDR_ICMP) {

+						struct icmp6hdr *icmph = (struct icmp6hdr *)(((unsigned char *)iph) + sizeof(struct ipv6hdr));

+						sc_debug_info_record("cap_net", "%u-%pI6-%pI6-%u %u:%u/%u\n",

+											pbuf_temp->dev, iph->saddr.s6_addr32, iph->daddr.s6_addr32,

+											iph->nexthdr, icmph->icmp6_type, icmph->icmp6_code,skb->len);

+					} else {

+						sc_debug_info_record("cap_net", "%u-%pI6-%pI6-%u/%u\n",

+											pbuf_temp->dev, iph->saddr.s6_addr32, iph->daddr.s6_addr32,

+											iph->nexthdr, skb->len);

+					}

+					break;

+				}

+				case ETH_P_ARP: {

+					struct zvnet_arphdr *arph = (struct zvnet_arphdr *)(skb->data + ETH_HLEN + l2_hdr_len);

+					sc_debug_info_record("cap_net", "%u:%04x-%pI4-%pI4-%u/%u\n",

+										pbuf_temp->dev, h_proto, arph->ar_sip, arph->ar_tip, htons(arph->ar_op), skb->len);

+					break;

+				}

+				case ETH_P_8021Q: {

+					struct vlan_hdr *vlanh = (struct vlan_hdr *)(skb->data + ETH_HLEN + l2_hdr_len);

+					sc_debug_info_record("cap_net", "%u:%04x-%u\n",

+										pbuf_temp->dev, h_proto, htons(vlanh->h_vlan_TCI) & VLAN_VID_MASK);

+					l2_hdr_len += VLAN_HLEN;

+					h_proto = htons(vlanh->h_vlan_encapsulated_proto);

+					goto again;

+				}

+				default:

+					sc_debug_info_record("cap_net", "%u:%04x/%u\n", pbuf_temp->dev, h_proto, skb->len);

+			}

+		}

+		atomic_set(&g_zvnet_pm_flag, 0);

+	}

+/* Ended by AICoder, pid:j2d34uccf7y1f37146a108290182771184940711 */

 	return skb;

 }

 

@@ -400,6 +536,11 @@
 		buff[i].len = skb->len;

 		buff[i].end_off = skb->end - skb->head;

 		buff[i].dev = zvnet_get_index_by_netdev(skb->dev);

+		if(unlikely(g_trace_limit & 2)){

+			printk("-%s-dump_toap-start-%d\n", skb->dev->name, skb->len);

+			zvnet_dump_packet(skb->data, skb->len, g_trace_limit);

+			printk("-%s-dump_toap-end-\n", skb->dev->name);

+		}

 		if(skb->capHead){

 			buff[i].buff = skb->capHead;

 #ifdef CONFIG_FASTNAT_MODULE

@@ -500,11 +641,11 @@
 	data->dev = net;

 	data->isToap = 1;

 	v7_dma_map_area(data->head, data->end - data->head + sizeof(struct skb_shared_info), DMA_TO_DEVICE);

+	net->stats.tx_packets++;

+	net->stats.tx_bytes += data->len;

 	skb_queue_tail(&g_zvnet_skb_xmit_queue, data);

 	if(data->len < g_wrap_packet_size || g_zvnet_skb_xmit_queue.qlen > g_wrap_num)

 		up(&g_zvnet_xmit_sem);

-	net->stats.tx_packets++;

-	net->stats.tx_bytes += skb->len;

 #else

     struct zvnet *dev = netdev_priv(net);

     struct zvnet_device *zvnetdev = (struct zvnet_device *)dev->dev_priv;

@@ -1240,6 +1381,7 @@
     struct net_device *net = NULL;

     struct zvnet_device *zvnetdev = NULL;

 

+	atomic_set(&g_zvnet_pm_flag, 0);

 #ifdef USE_ZVNET_PACKET

 			skb_queue_head_init(&g_zvnet_skb_xmit_queue);

 			spin_lock_init(&g_zvnet_free_lock);