Only in lip_katm: CVS
Only in lip_katm: mod
Only in lip_katm: tmp
diff -dur lip_katm.orig/wanpipe_katm.h lip_katm/wanpipe_katm.h
--- lip_katm.orig/wanpipe_katm.h	2007-03-16 16:41:23.000000000 -0500
+++ lip_katm/wanpipe_katm.h	2007-04-20 21:45:05.537688296 -0400
@@ -2,10 +2,12 @@
 #ifndef _WAN_KATM_H_
 #define _WAN_KATM_H_ 1 
 
-#include "stddef.h"
-#include <linux/types.h>
-#include "wanpipe_abstr.h"
-#include "wanpipe_cfg.h"
+#include <wanpipe_lip.h>
+
+//#include <linux/types.h>
+//#include "wanpipe_abstr.h"
+//#include "wanpipe_cfg.h"
+
 
 /* This is the shared header between the LIP
  * and this PROTOCOL */
@@ -30,25 +32,34 @@
 #define AAL5_CRC32_MASK	(0xDEBB20E3) /* CRC-32 Mask */
 
 
+struct wp_katm_channel;
+
+
 typedef struct _katm_ 
 {
-	unsigned long		critical;
+	unsigned long			critical;
 	
 	/* Used by lip layer */
-	void 			*link_dev;
-	void 			*dev;
+	void 				*link_dev;
+	void 				*dev;
 	
-	unsigned char		type;
-	wplip_prot_reg_t	reg;
-	wan_atm_conf_if_t	cfg;
-	unsigned char 		name[WPIFNAMSIZ+1];
-	unsigned char 		hwdevname[WPIFNAMSIZ+1];
+	unsigned char			type;
+	wplip_prot_reg_t		reg;
+	wan_atm_conf_if_t		cfg;
+	unsigned char 			name[WPIFNAMSIZ+1];
+	unsigned char 			hwdevname[WPIFNAMSIZ+1];
 	int				state;
-	unsigned int 		refcnt;
 	
 	/* INSERT PROTOCOL SPECIFIC VARIABLES HERE */
 	void				*atmdev;  //
 	void				*sar_dev; 
+	
+	WAN_LIST_HEAD(,wp_katm_channel)	list_head_ifdev;
+	unsigned int			dev_cnt;
+	wan_rwlock_t			dev_list_lock; 
+	struct wp_katm_channel		*cur_tx;
+	
+	atomic_t			refcnt;
 } wp_katm_t;
 
 
@@ -95,6 +106,11 @@
     /* Link back to the wp_katm_t device */
     wp_katm_t *atm_link;
     void *sar_vcc;
+    
+    wan_skb_queue_t			tx_queue;
+    
+    WAN_LIST_ENTRY(wp_katm_channel)	list_entry;
+    atomic_t			refcnt;
 
 } wp_katm_channel_t;
 
@@ -109,6 +125,9 @@
 		      void *optval, int optlen);
 int wan_lip_katm_sg_send(struct atm_vcc *vcc, unsigned long start,
 		   unsigned long size);
+int wpkatm_priv_bh (wp_katm_t *atm_link);
+void wpkatm_insert_vccdev(wp_katm_t *atm_link, wp_katm_channel_t *atm_chan);
+void wpkatm_remove_vccdev(wp_katm_t *atm_link, wp_katm_channel_t *atm_chan);
 //int wp_katm_activate_channel(struct atm_vcc *vcc, wp_katm_channel_t *chan);
 
 /* ATM Callbacks */
@@ -123,32 +142,6 @@
 					  
 
 
-/* PRIVATE Debug Functions */
-
-#define wp_dev_hold(dev)    do{\
-				wpabs_debug_test("%s:%d (dev_hold) Refnt %i!\n",\
-							__FUNCTION__,__LINE__,dev->refcnt );\
-				dev->refcnt++; \
-			    }while(0)
-
-#define wp_dev_put(dev)	    do{\
-				wpabs_debug_test("%s:%d (wp_dev_put): Refnt %i!\n",\
-							__FUNCTION__,__LINE__,dev->refcnt );\
-				if (--dev->refcnt == 0){\
-					wpabs_debug_test("%s:%d (wp_dev_put): Deallocating!\n",\
-							__FUNCTION__,__LINE__);\
-					wpabs_free(dev);\
-					dev=NULL;\
-				}\
-		            }while(0)
-
-#define FUNC_BEGIN() wpabs_debug_test("%s:%d ---Begin---\n",__FUNCTION__,__LINE__); 
-#define FUNC_END() wpabs_debug_test("%s:%d ---End---\n\n",__FUNCTION__,__LINE__); 
-
-#define FUNC_BEGIN1() wpabs_debug_event("%s:%d ---Begin---\n",__FUNCTION__,__LINE__); 
-#define FUNC_END1() wpabs_debug_event("%s:%d ---End---\n\n",__FUNCTION__,__LINE__); 
-
-
 #endif
 
 
Only in lip_katm: wanpipe_katm.h~
diff -dur lip_katm.orig/wanpipe_katm_iface.c lip_katm/wanpipe_katm_iface.c
--- lip_katm.orig/wanpipe_katm_iface.c	2007-03-16 16:41:23.000000000 -0500
+++ lip_katm/wanpipe_katm_iface.c	2007-04-20 21:45:05.536688448 -0400
@@ -53,9 +53,6 @@
 int wp_katm_tx(void *prot_ptr, void *skb, int type)
 /********************************************************************************************/
 {
-	wp_katm_t *prot = (wp_katm_t *)prot_ptr;
-	int err;
-
 	/* This function is not used */
 	
 	wpabs_debug_event("%s %d\n",
@@ -102,7 +99,7 @@
 	struct atm_dev *atmdev;
 	wplip_prot_reg_t katm_callback_ops;
 
-	int x=0;
+
 
 	FUNC_BEGIN();
 
@@ -124,9 +121,14 @@
 
 	/* Copy the LIP call back functions used to call
 	 * the LIP layer */
+	wpabs_memset(atm_link,0,sizeof(wp_katm_t));
 	wpabs_memcpy(&atm_link->reg,prot_reg,sizeof(wplip_prot_reg_t));
 	wpabs_strncpy(atm_link->name,devname,sizeof(atm_link->name)-1);
 	
+	wpabs_memcpy(&atm_link->cfg,cfg_ptr,sizeof(atm_link->cfg));
+	
+	atm_link->dev_list_lock=RW_LOCK_UNLOCKED;
+	
 	/* INITIALIZE THE PROTOCOL HERE */
 	atmdev = atm_dev_register(devname, &ops, -1, NULL);
 	if (atmdev == NULL) {
@@ -186,6 +188,8 @@
 	wpabs_debug_test("%s: %s %d\n",
 			atm_link->name,__FUNCTION__,__LINE__);
 	
+	wan_set_bit(0,&atm_link->critical);		
+			
 	FUNC_BEGIN();
 	
 	wp_unregister_atm_prot(atm_link->sar_dev);
@@ -341,6 +345,12 @@
 	return 0;
 }
 
+
+int wpkatm_bh (void *atm_link)
+{
+	return wpkatm_priv_bh(atm_link);
+}
+
 /*======================================================
  * wp_katm_data_indication
  *
@@ -404,3 +414,139 @@
 		prot->reg.chan_set_state(prot->dev,WAN_DISCONNECTED,NULL,0);
 	}
 }
+
+int wpkatm_atmdev_tx(wp_katm_channel_t *atm_dev)
+{
+	wp_katm_t *atm_link = atm_dev->atm_link;
+	netskb_t *skb;
+	int err=0;
+	
+	skb=wan_skb_dequeue(&atm_dev->tx_queue);
+	if (skb){
+		
+		if (atm_link->dev && atm_link->reg.tx_chan_down){
+			err = atm_link->reg.tx_chan_down(atm_link->dev,skb);
+		}else{
+			wpabs_debug_event("%s: %s %d ERROR no tx_chan_down \n",
+				atm_dev->name,__FUNCTION__,__LINE__);
+			wpabs_skb_free(skb);
+			return -1;
+		}
+
+		if (err != 0){
+			wan_skb_queue_head(&atm_dev->tx_queue,skb);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
+
+int wpkatm_priv_bh (wp_katm_t *atm_link)
+{
+	wp_katm_channel_t *atm_dev=NULL;
+	int err=0;
+	unsigned int timeout_cnt=200;
+	int moretx=0;
+	unsigned long flags;
+
+	if (!atm_link) {
+		return -1;
+	}
+	
+	if (wan_test_bit(0,&atm_link->critical) ) {
+		DEBUG_EVENT("%s: KATM BH Down\n",
+					atm_link->name);
+		return -1;
+	}
+	
+	if (wan_test_and_set_bit(1,&atm_link->critical)) {
+		return -1;
+	}
+	
+	WP_READ_LOCK(&atm_link->dev_list_lock,flags);
+	
+	atm_dev=WAN_LIST_FIRST(&atm_link->list_head_ifdev);
+	if (!atm_dev){
+		goto wpkatm_bh_transmit_exit;
+	}
+	
+	for (;;) {
+		if (--timeout_cnt == 0){
+			DEBUG_EVENT("%s: ATMDEV Priority TxBH Time squeeze\n",atm_link->name);
+			break;
+		}
+
+		if (!wan_test_bit(ATM_VF_READY,&atm_dev->vcc->flags)) {
+			break;
+		}
+		
+		err = wpkatm_atmdev_tx(atm_dev);
+		if (err){
+			break;
+		}
+		
+		if (wan_skb_queue_len(&atm_dev->tx_queue) == 0) {
+			break;
+		}
+	}
+	
+	timeout_cnt=5000;
+
+	if ((atm_dev=atm_link->cur_tx) == NULL){
+
+		atm_dev=WAN_LIST_FIRST(&atm_link->list_head_ifdev);
+		if (!atm_dev){
+			goto wpkatm_bh_transmit_exit;
+		}
+
+		atm_link->cur_tx=atm_dev;
+	}
+	
+	
+	for (;;){
+
+		if (--timeout_cnt == 0){
+			DEBUG_EVENT("%s: LipDev TxBH Time squeeze\n",atm_link->name);
+			goto wpkatm_bh_transmit_exit;
+		}
+
+		if (!wan_test_bit(ATM_VF_READY,&atm_dev->vcc->flags)) {
+			goto wpkatm_bh_transmit_skip;
+		}
+		
+		err = wpkatm_atmdev_tx(atm_dev);
+		if (err){
+			if (wan_skb_queue_len(&atm_dev->tx_queue)) {
+				moretx=1;
+			}
+			goto wpkatm_bh_transmit_exit;
+		}
+		
+		if (wan_skb_queue_len(&atm_dev->tx_queue)) {
+			moretx=1;
+		}
+		
+wpkatm_bh_transmit_skip:
+
+		atm_dev=WAN_LIST_NEXT(atm_dev,list_entry);
+		if (atm_dev == NULL){
+			atm_dev=WAN_LIST_FIRST(&atm_link->list_head_ifdev);
+		}
+
+		if (atm_dev == atm_link->cur_tx){
+			/* We went through the whole list */
+			break;
+		}
+	}
+
+wpkatm_bh_transmit_exit:
+
+	atm_link->cur_tx=atm_dev;
+	WP_READ_UNLOCK(&atm_link->dev_list_lock,flags);
+	wan_clear_bit(1,&atm_link->critical);
+	
+	return moretx;
+
+}                   
Only in lip_katm: wanpipe_katm_iface.c~
Only in lip_katm: wanpipe_katm_iface.o
Only in lip_katm: .wanpipe_katm_iface.o.cmd
diff -dur lip_katm.orig/wanpipe_katm_sub.c lip_katm/wanpipe_katm_sub.c
--- lip_katm.orig/wanpipe_katm_sub.c	2007-03-16 16:41:23.000000000 -0500
+++ lip_katm/wanpipe_katm_sub.c	2007-04-20 21:45:05.537688296 -0400
@@ -38,7 +38,7 @@
 {
 	unsigned char tx_tclass = vcc->qos.txtp.traffic_class;
 	unsigned char rx_tclass = vcc->qos.rxtp.traffic_class;
-	//wp_katm_t *atm_link = vcc->dev->dev_data; 
+	wp_katm_t *atm_link = vcc->dev->dev_data; 
 	wp_katm_channel_t *chan = vcc->dev_data;
 	if (!chan) {
 		wpabs_debug_event("%s:%d Error no device\n",__FUNCTION__,__LINE__);
@@ -67,6 +67,8 @@
 	wp_unregister_atm_chan(chan->sar_vcc);
 	chan->sar_vcc=NULL;
 	
+	wpkatm_remove_vccdev(atm_link,chan);
+	
 	if(vcc->dev_data) //insurance against locking up
 		kfree(vcc->dev_data); //Free the chan struct we created in Open
 	vcc->dev_data = NULL;
@@ -206,6 +208,8 @@
 		return result;
 	}
 
+	wpkatm_insert_vccdev(atm_link,chan);
+	
 	/* Tells the stack that this VC is ready for Tx/Rx */
 	wpabs_set_bit(ATM_VF_READY,&vcc->flags);
 
@@ -278,12 +282,16 @@
 		wpabs_skb_free(nskb);
 		if (vcc->pop) vcc->pop(vcc,skb);
 		else dev_kfree_skb(skb);
+		
+		wpkatm_priv_bh(atm_link);
+		
 		return -1;
 	}
 		
 	if (vcc->pop) vcc->pop(vcc,skb);
 	else dev_kfree_skb(skb);
 	
+	wpkatm_priv_bh(atm_link);
 	
 //	wpabs_debug_event("%s:%d Send OK\n",
 //			__FUNCTION__,__LINE__);
@@ -361,6 +369,7 @@
 	return 0;
 }
 
+#define KATM_MAX_Q 200
 int wplip_katm_callback_tx_down (void *lip_dev_ptr, void *skb)
 {
 	wp_katm_channel_t *chan = (wp_katm_channel_t *)lip_dev_ptr;
@@ -373,19 +382,25 @@
 		}
 		return 0;
 	}
+	
+	if (!skb){
+		int free_space=KATM_MAX_Q - wan_skb_queue_len(&chan->tx_queue);	
+		if (free_space < 0) {
+			return 0;
+		} else {
+			return free_space;
+		}    
+	}
 
-//	wpabs_debug_event("%s: %s %d len=%i\n",
-//			chan->name,__FUNCTION__,__LINE__,skb?wpabs_skb_len(skb):-1);
-
-
-	if (chan->atm_link->dev && chan->atm_link->reg.tx_chan_down){
-		return chan->atm_link->reg.tx_chan_down(chan->atm_link->dev,skb);
-        }else{
-		wpabs_debug_event("%s: %s %d ERROR no tx_chan_down \n",
-			chan->name,__FUNCTION__,__LINE__);
-		wpabs_skb_free(skb);
-        }
-
+	if (wan_skb_queue_len(&chan->tx_queue) >= KATM_MAX_Q){
+		DEBUG_EVENT("%s: %s() Error  Tx queue full\n",
+				chan->name,__FUNCTION__);
+		return 1;
+	}
+	
+	
+	wan_skb_queue_tail(&chan->tx_queue,skb);
+		
 	return 0;
 }
 
@@ -409,7 +424,30 @@
 }
 
 
+void wpkatm_insert_vccdev(wp_katm_t *atm_link, wp_katm_channel_t *atm_chan)
+{
+	unsigned long flags;
+
+	WP_WRITE_LOCK(&atm_link->dev_list_lock,flags);
+	WAN_LIST_INSERT_HEAD(&atm_link->list_head_ifdev,atm_chan,list_entry);
+	WAN_DEV_HOLD(atm_chan);
+	atm_link->dev_cnt++;
+	WP_WRITE_UNLOCK(&atm_link->dev_list_lock,flags);
+}
+
+
+void wpkatm_remove_vccdev(wp_katm_t *atm_link, wp_katm_channel_t *atm_chan)
+{
+	unsigned long flags;
+	
+	WP_WRITE_LOCK(&atm_link->dev_list_lock,flags);
+	WAN_DEV_PUT(atm_chan);
+	WAN_LIST_REMOVE(atm_chan,list_entry);
+	atm_link->dev_cnt--;
+	WP_WRITE_UNLOCK(&atm_link->dev_list_lock,flags);
 
+	return;
+}
 
 
 
Only in lip_katm: wanpipe_katm_sub.c~
Only in lip_katm: wanpipe_katm_sub.o
Only in lip_katm: .wanpipe_katm_sub.o.cmd
