--- sdla_xilinx.c	2007-01-09 16:59:16.718380640 -0500
+++ /common/wanpipe/sdla_xilinx.c	2007-01-09 15:02:48.096812608 -0500
@@ -54,6 +54,11 @@
 };
 
 enum {
+	AFT_CHIP_CONFIGURED,
+	AFT_FRONT_END_UP,
+};
+
+enum {
 	AFT_FE_CFG_ERR,
 	AFT_FE_CFG,
 	AFT_FE_INTR,
@@ -263,7 +268,7 @@
 static void 	disable_comm (sdla_t *card);
 
 /* Interrupt handlers */
-static void 	wp_xilinx_isr (sdla_t* card);
+static WAN_IRQ_RETVAL 	wp_xilinx_isr (sdla_t* card);
 
 /* Bottom half handlers */
 #if defined(__LINUX__)
@@ -628,9 +633,14 @@
 
 	WAN_TASKQ_INIT((&card->u.aft.port_task),0,aft_port_task,card);
 
+	/* Set protocol link state to disconnected,
+	 * After seting the state to DISCONNECTED this
+	 * function must return 0 i.e. success */
+	port_set_state(card,WAN_CONNECTING);
+        card->isr = &wp_xilinx_isr;
+
 	xilinx_delay(1);
 #if !defined(CONFIG_PRODUCT_WANPIPE_GENERIC)
-        card->isr = &wp_xilinx_isr;
 	err=xilinx_chip_configure(card);
 	if (err){
 		xilinx_chip_unconfigure(card);
@@ -640,10 +650,18 @@
 
 	xilinx_delay(1);
 
-	/* Set protocol link state to disconnected,
-	 * After seting the state to DISCONNECTED this
-	 * function must return 0 i.e. success */
-	port_set_state(card,WAN_CONNECTING);
+	wan_set_bit(AFT_CHIP_CONFIGURED,&card->u.aft.chip_cfg_status);
+
+	if (wan_test_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status)){
+		wan_smp_flag_t smp_flags;
+		DEBUG_TEST("%s: Front end up, retrying enable front end!\n",
+				card->devname);
+		wan_spin_lock_irq(&card->wandev.lock,&smp_flags);
+		handle_front_end_state(card);
+		wan_spin_unlock_irq(&card->wandev.lock,&smp_flags);
+
+		wan_clear_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status);
+	}        
 
 	DEBUG_EVENT("%s: Configuring Device   :%s FrmVr=%02X\n",
 			card->devname,card->devname,card->u.aft.firm_ver);
@@ -1489,8 +1507,8 @@
 		wan_clear_bit(0,&conf->active_ch);
 	}
 
-#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE)
 	if (strcmp(conf->usedby, "TDM_VOICE") == 0 ) {
+#if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE)
 		if (card->u.aft.cfg.tdmv_span_no){
 			/* Initialize TDMV interface function */
 			err = wp_tdmv_te1_init(&card->tdmv_iface);
@@ -1507,8 +1525,15 @@
 				return err;
 			}
 		}
+#else
+		DEBUG_EVENT("\n");
+		DEBUG_EVENT("%s: Error: TDM VOICE prot not compiled\n",
+					card->devname);
+		DEBUG_EVENT("%s:        during installation process!\n",
+					card->devname);
+		return -EINVAL;
+#endif
 	}
-#endif         
 
 	if (strcmp(conf->usedby, "TDM_VOICE") == 0 ||
 	    strcmp(conf->usedby, "TDM_VOICE_API") == 0){
@@ -1673,8 +1698,6 @@
 		wan_free(chan->tx_realign_buf);
 		chan->tx_realign_buf=NULL;
 	}
-		
-	chan->logic_ch_num=-1;
 
 	/* Delete interface name from proc fs. */
 #if 0
@@ -1889,12 +1912,12 @@
 	int err = 0;
 
 #ifdef CONFIG_PRODUCT_WANPIPE_GENERIC
-        card->isr = &wp_xilinx_isr;
 	err=xilinx_chip_configure(card);
 	if (err){
 		xilinx_chip_unconfigure(card);
 		return -EINVAL;
 	}
+        card->isr = &wp_xilinx_isr;
 	
 	err=xilinx_dev_configure(card, chan);
 	if (err){
@@ -1947,17 +1970,17 @@
 		disable_data_error_intr(card,LINK_DOWN);
 		enable_data_error_intr(card);
 	}
-	
-	wan_spin_unlock_irq(&card->wandev.lock,&flags);
-
-	/* Increment the module usage count */
-	wanpipe_open(card);
 
         if (card->wandev.state == WAN_CONNECTED){
                 /* If Front End is connected already set interface
                  * state to Connected too */
                 set_chan_state(card, dev, WAN_CONNECTED);
         }
+                  
+	wan_spin_unlock_irq(&card->wandev.lock,&flags);
+
+	/* Increment the module usage count */
+	wanpipe_open(card);
 
 	protocol_start(card,dev);
 
@@ -2052,13 +2075,16 @@
 	/* TE1 - Unconfiging, only on shutdown */
 	if (IS_TE1_CARD(card)) {
 		wan_smp_flag_t smp_flags,smp_flags1;
-		wan_spin_lock_irq(&card->wandev.lock, &smp_flags);
+		if (card->wandev.fe_iface.pre_release){
+			card->wandev.fe_iface.pre_release(&card->fe);
+		}
 		card->hw_iface.hw_lock(card->hw,&smp_flags1);
+		wan_spin_lock_irq(&card->wandev.lock, &smp_flags);
 		if (card->wandev.fe_iface.unconfig){
 			card->wandev.fe_iface.unconfig(&card->fe);
 		}
-		card->hw_iface.hw_unlock(card->hw,&smp_flags1);
 		wan_spin_unlock_irq(&card->wandev.lock, &smp_flags);
+		card->hw_iface.hw_unlock(card->hw,&smp_flags1);
 	}
 
 
@@ -2119,6 +2145,14 @@
 	wan_netif_set_ticks(dev, SYSTEM_TICKS);
 
 	WAN_NETIF_WAKE_QUEUE(dev);	/*netif_wake_queue (dev);*/
+
+	if (chan->common.usedby == API){
+# if defined(__LINUX__)
+		wan_wakeup_api(chan);
+# endif
+	}else if (chan->common.usedby == STACK){
+		wanpipe_lip_kick(chan,0);
+	}           
 }
 
 
@@ -2658,6 +2692,10 @@
                                 	(IS_T1_CARD(card))?"T1":"E1");
                	return -EINVAL;
        	}
+	/* Run rest of initialization not from lock */
+	if (card->wandev.fe_iface.post_init){
+		err=card->wandev.fe_iface.post_init(&card->fe);
+	}
 
 	xilinx_delay(1);
 
@@ -3100,8 +3138,7 @@
 		free_fifo_baddr_and_size(card,chan);
 		wan_spin_unlock_irq(&card->wandev.lock,&smp_flags);
 
-		/* Do not clear logic channel here,
-		   do it at the end of del_if_private */
+		chan->logic_ch_num=-1;
 
 		for (i=0;i<card->u.aft.num_of_time_slots;i++){
 			if (wan_test_bit(i,&chan->time_slot_map)){
@@ -4099,19 +4136,36 @@
 		}
 	}
 
+
 	if (len > aft_rx_copyback){
 
+#if defined(__OpenBSD__)
+		/* Try not to return our mbuf to the kernel.
+		** Still possibility that firmware can use the hardware pointer 
+		** (not confirmed yet) */
+		*new_skb=wan_skb_alloc(len + 20);
+		if (!*new_skb){
+			DEBUG_EVENT("%s:%s: Failed to allocate rx skb pkt (len=%d)!\n",
+				card->devname,chan->if_name,(len+20));
+			chan->if_stats.rx_dropped++;
+			goto rx_comp_error;
+		}
+
+		buf=wan_skb_put((*new_skb),len);
+		memcpy(buf, wan_skb_tail(skb),len);
+
+		aft_init_requeue_free_skb(chan, skb);
+#else	
 		/* The rx size is big enough, thus
 		 * send this buffer up the stack
 		 * and allocate another one */
-		memset(wan_skb_data(skb),0,sizeof(wp_rx_element_t));
 		wan_skb_put(skb,len);	
 		wan_skb_pull(skb, sizeof(wp_rx_element_t));
 		*new_skb=skb;
 		
 		aft_alloc_rx_dma_buff(card,chan,1,1);
-
-	}else{
+#endif
+	} else {
 
 		/* The rx packet is very
 		 * small thus, allocate a new 
@@ -4271,7 +4325,6 @@
 }
 #endif
 
-
 static int aft_alloc_rx_dma_buff(sdla_t *card, private_area_t *chan, int num, int irq)
 {
 	int i;
@@ -4292,7 +4345,9 @@
 	}
 
 	return 0;
-}                
+}
+
+
 
 
 /*============================================================================
@@ -4306,10 +4361,15 @@
 	wan_set_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd);
 	WAN_TASKQ_SCHEDULE((&card->u.aft.port_task));
 #else	
-	wan_smp_flag_t		smp_flags;
+	wan_smp_flag_t	smp_flags;
+	int		err = 0;
 	wan_spin_lock_irq(&card->wandev.lock, &smp_flags);
-	card->wandev.fe_iface.polling(&card->fe);
+	err = card->wandev.fe_iface.polling(&card->fe);
 	wan_spin_unlock_irq(&card->wandev.lock, &smp_flags);
+	if (err == 1 && card->wandev.fe_iface.add_timer){
+		/* need to schedule timer */
+		err = card->wandev.fe_iface.add_timer(&card->fe);
+	}
 #endif
 
 	DEBUG_TEST("%s: %s Sdla Polling End!\n",
@@ -4700,15 +4760,16 @@
  * Determin the interrupt received and handle it.
  *
  */
-static void wp_xilinx_isr (sdla_t* card)
+static WAN_IRQ_RETVAL wp_xilinx_isr (sdla_t* card)
 {
     	int i;
 	u32 reg;
 	u32 dma_tx_reg,dma_rx_reg,tx_fifo_status=0,rx_fifo_status=0;
 	private_area_t *chan;
+	WAN_IRQ_RETVAL_DECL(irq_ret);
 
 	if (wan_test_bit(CARD_DOWN,&card->wandev.critical)){
-		return;
+		WAN_IRQ_RETURN(irq_ret);
 	}
 
     	wan_set_bit(0,&card->in_isr);
@@ -4735,6 +4796,7 @@
 
 			port_set_state(card,WAN_DISCONNECTED);
 			disable_data_error_intr(card,DEVICE_DOWN);
+			WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED);
 			goto isr_end;
 		}
 	}else{
@@ -4759,6 +4821,7 @@
 #else
               		front_end_interrupt(card,reg,0);
 #endif
+			WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED);
 		}
         }
 
@@ -4777,6 +4840,7 @@
 			tx_fifo_status&=card->u.aft.active_ch_map;
 
 			fifo_error_interrupt(card,reg,tx_fifo_status,rx_fifo_status);
+			WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED);
 		}
 	}
 
@@ -4789,6 +4853,7 @@
     	if (wan_test_bit(GLOBAL_INTR_ENABLE_BIT,&reg) &&
             (wan_test_bit(DMA_INTR_FLAG,&reg) || rx_fifo_status) ){
 
+		WAN_IRQ_RETVAL_SET(irq_ret, WAN_IRQ_HANDLED);
 
         	/* Receive DMA Engine */
 		card->hw_iface.bus_read_4(card->hw,
@@ -4919,7 +4984,8 @@
 
     	DEBUG_ISR("---- ISR end.-------------------\n");
     	wan_clear_bit(0,&card->in_isr);
-	return;
+
+	WAN_IRQ_RETURN(irq_ret);
 }
 
 
@@ -5330,10 +5396,18 @@
 		return;
 	}
 
+	if (!wan_test_bit(AFT_CHIP_CONFIGURED,&card->u.aft.chip_cfg_status)&&
+	    card->fe.fe_status == FE_CONNECTED){
+		DEBUG_TEST("%s: Skipping Front Front End State = %x\n",
+				card->devname,card->fe.fe_status);
+				
+		wan_set_bit(AFT_FRONT_END_UP,&card->u.aft.chip_cfg_status);
+		return;
+	}      
+
 	if (card->fe.fe_status == FE_CONNECTED){
 
 		if (!wan_test_bit(0,&card->u.aft.comm_enabled)){
-			port_set_state(card,WAN_CONNECTED);
 #if defined(CONFIG_PRODUCT_WANPIPE_TDM_VOICE)
 			if (card->wan_tdmv.sc){
 				int	err;
@@ -5341,6 +5415,7 @@
 			}
 #endif
 			enable_data_error_intr(card);
+			port_set_state(card,WAN_CONNECTED);
 
 			aft_red_led_ctrl(card, AFT_LED_OFF);
 			card->wandev.fe_iface.led_ctrl(&card->fe, AFT_LED_ON);
@@ -6895,13 +6970,18 @@
 	if (wan_test_bit(AFT_FE_POLL,&card->u.aft.port_task_cmd)){
 		aft_fe_intr_ctrl(card, 0);
 		if (card->wandev.fe_iface.polling){
-			wan_smp_flag_t smp_flags;
+			wan_smp_flag_t	smp_flags;
+			int		err = 0; 
 
-			card->wandev.fe_iface.polling(&card->fe);
+			err = card->wandev.fe_iface.polling(&card->fe);
 
 			wan_spin_lock_irq(&card->wandev.lock,&smp_flags);
 			handle_front_end_state(card);
 			wan_spin_unlock_irq(&card->wandev.lock,&smp_flags);
+			if (err == 1 && card->wandev.fe_iface.add_timer){
+				/* need to schedule timer */
+				err = card->wandev.fe_iface.add_timer(&card->fe);
+			}			
 		}
 
 		aft_fe_intr_ctrl(card, 1);
