ia64/xen-unstable

changeset 1774:131c48baa117

bitkeeper revision 1.1071.1.5 (40f41ae00utn5d2f3tlNLcvG_QhiBA)

Fairly major fixes to the network frontend driver.
Much saner now.
author kaf24@scramble.cl.cam.ac.uk
date Tue Jul 13 17:24:48 2004 +0000 (2004-07-13)
parents c82c495264af
children ad09d919356e
files linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c
line diff
     1.1 --- a/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c	Tue Jul 13 15:24:53 2004 +0000
     1.2 +++ b/linux-2.4.26-xen-sparse/arch/xen/drivers/netif/frontend/main.c	Tue Jul 13 17:24:48 2004 +0000
     1.3 @@ -1,7 +1,7 @@
     1.4  /******************************************************************************
     1.5   * arch/xen/drivers/netif/frontend/main.c
     1.6   * 
     1.7 - * Virtual network driver for XenoLinux.
     1.8 + * Virtual network driver for conversing with remote driver backends.
     1.9   * 
    1.10   * Copyright (c) 2002-2004, K A Fraser
    1.11   */
    1.12 @@ -36,7 +36,6 @@
    1.13  
    1.14  static void network_tx_buf_gc(struct net_device *dev);
    1.15  static void network_alloc_rx_buffers(struct net_device *dev);
    1.16 -static void cleanup_module(void);
    1.17  
    1.18  static unsigned long rx_pfn_array[NETIF_RX_RING_SIZE];
    1.19  static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE+1];
    1.20 @@ -63,11 +62,16 @@ struct net_private
    1.21      unsigned int evtchn;
    1.22      unsigned int irq;
    1.23  
    1.24 -#define NETIF_STATE_CLOSED       0
    1.25 -#define NETIF_STATE_DISCONNECTED 1
    1.26 -#define NETIF_STATE_CONNECTED    2
    1.27 -#define NETIF_STATE_ACTIVE       3
    1.28 -    unsigned int state;
    1.29 +    /* What is the status of our connection to the remote backend? */
    1.30 +#define BEST_CLOSED       0
    1.31 +#define BEST_DISCONNECTED 1
    1.32 +#define BEST_CONNECTED    2
    1.33 +    unsigned int backend_state;
    1.34 +
    1.35 +    /* Is this interface open or closed (down or up)? */
    1.36 +#define UST_CLOSED        0
    1.37 +#define UST_OPEN          1
    1.38 +    unsigned int user_state;
    1.39  
    1.40      /*
    1.41       * {tx,rx}_skbs store outstanding skbuffs. The first entry in each
    1.42 @@ -135,7 +139,8 @@ static int netctrl_err(int err)
    1.43  static int netctrl_connected(void)
    1.44  {
    1.45      int ok = 0;
    1.46 -    ok = (netctrl.err ? netctrl.err : (netctrl.connected_n == netctrl.interface_n));
    1.47 +    ok = (netctrl.err ? netctrl.err :
    1.48 +          (netctrl.connected_n == netctrl.interface_n));
    1.49      return ok;
    1.50  }
    1.51  
    1.52 @@ -152,12 +157,13 @@ static int netctrl_connected_count(void)
    1.53  
    1.54      connected = 0;
    1.55      
    1.56 -    list_for_each(ent, &dev_list) {
    1.57 +    list_for_each(ent, &dev_list)
    1.58 +    {
    1.59          np = list_entry(ent, struct net_private, list);
    1.60 -        if ( np->state == NETIF_STATE_CONNECTED){
    1.61 +        if ( np->backend_state == BEST_CONNECTED )
    1.62              connected++;
    1.63 -        }
    1.64      }
    1.65 +
    1.66      netctrl.connected_n = connected;
    1.67      return connected;
    1.68  }
    1.69 @@ -165,32 +171,16 @@ static int netctrl_connected_count(void)
    1.70  static int network_open(struct net_device *dev)
    1.71  {
    1.72      struct net_private *np = dev->priv;
    1.73 -    int i;
    1.74  
    1.75 -    if ( np->state != NETIF_STATE_CONNECTED )
    1.76 -        return -EINVAL;
    1.77 -
    1.78 -    np->rx_resp_cons = np->tx_resp_cons = np->tx_full = 0;
    1.79      memset(&np->stats, 0, sizeof(np->stats));
    1.80 -    spin_lock_init(&np->tx_lock);
    1.81 -    spin_lock_init(&np->rx_lock);
    1.82  
    1.83 -    /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
    1.84 -    for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ )
    1.85 -        np->tx_skbs[i] = (void *)(i+1);
    1.86 -    for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ )
    1.87 -        np->rx_skbs[i] = (void *)(i+1);
    1.88 -
    1.89 -    wmb();
    1.90 -    np->state = NETIF_STATE_ACTIVE;
    1.91 +    np->user_state = UST_OPEN;
    1.92  
    1.93      network_alloc_rx_buffers(dev);
    1.94      np->rx->event = np->rx_resp_cons + 1;
    1.95  
    1.96      netif_start_queue(dev);
    1.97  
    1.98 -    MOD_INC_USE_COUNT;
    1.99 -
   1.100      return 0;
   1.101  }
   1.102  
   1.103 @@ -202,6 +192,9 @@ static void network_tx_buf_gc(struct net
   1.104      struct net_private *np = dev->priv;
   1.105      struct sk_buff *skb;
   1.106  
   1.107 +    if ( np->backend_state != BEST_CONNECTED )
   1.108 +        return;
   1.109 +
   1.110      do {
   1.111          prod = np->tx->resp_prod;
   1.112  
   1.113 @@ -233,7 +226,7 @@ static void network_tx_buf_gc(struct net
   1.114           ((np->tx->req_prod - prod) < NETIF_TX_RING_SIZE) )
   1.115      {
   1.116          np->tx_full = 0;
   1.117 -        if ( np->state == NETIF_STATE_ACTIVE )
   1.118 +        if ( np->user_state == UST_OPEN )
   1.119              netif_wake_queue(dev);
   1.120      }
   1.121  }
   1.122 @@ -249,7 +242,7 @@ static void network_alloc_rx_buffers(str
   1.123  
   1.124      /* Make sure the batch is large enough to be worthwhile (1/2 ring). */
   1.125      if ( unlikely((i - np->rx_resp_cons) > (NETIF_RX_RING_SIZE/2)) || 
   1.126 -         unlikely(np->state != NETIF_STATE_ACTIVE) )
   1.127 +         unlikely(np->backend_state != BEST_CONNECTED) )
   1.128          return;
   1.129  
   1.130      do {
   1.131 @@ -333,8 +326,7 @@ static int network_start_xmit(struct sk_
   1.132      
   1.133      spin_lock_irq(&np->tx_lock);
   1.134  
   1.135 -    /* if the backend isn't available then don't do anything! */
   1.136 -    if ( !netif_carrier_ok(dev) )
   1.137 +    if ( np->backend_state != BEST_CONNECTED )
   1.138      {
   1.139          spin_unlock_irq(&np->tx_lock);
   1.140          return 1;
   1.141 @@ -383,11 +375,11 @@ static void netif_int(int irq, void *dev
   1.142      unsigned long flags;
   1.143  
   1.144      spin_lock_irqsave(&np->tx_lock, flags);
   1.145 -    if ( likely(netif_carrier_ok(dev)) )
   1.146 -        network_tx_buf_gc(dev);
   1.147 +    network_tx_buf_gc(dev);
   1.148      spin_unlock_irqrestore(&np->tx_lock, flags);
   1.149  
   1.150 -    if ( np->rx_resp_cons != np->rx->resp_prod )
   1.151 +    if ( (np->rx_resp_cons != np->rx->resp_prod) &&
   1.152 +         (np->user_state == UST_OPEN) )
   1.153          netif_rx_schedule(dev);
   1.154  }
   1.155  
   1.156 @@ -406,8 +398,7 @@ static int netif_poll(struct net_device 
   1.157  
   1.158      spin_lock(&np->rx_lock);
   1.159  
   1.160 -    /* If the device is undergoing recovery then don't do anything. */
   1.161 -    if ( !netif_carrier_ok(dev) )
   1.162 +    if ( np->backend_state != BEST_CONNECTED )
   1.163      {
   1.164          spin_unlock(&np->rx_lock);
   1.165          return 0;
   1.166 @@ -430,7 +421,7 @@ static int netif_poll(struct net_device 
   1.167          if ( unlikely(rx->status <= 0) )
   1.168          {
   1.169              /* Gate this error. We get a (valid) slew of them on suspend. */
   1.170 -            if ( np->state == NETIF_STATE_ACTIVE )
   1.171 +            if ( np->user_state != UST_OPEN )
   1.172                  printk(KERN_ALERT "bad buffer on RX ring!(%d)\n", rx->status);
   1.173              dev_kfree_skb(skb);
   1.174              continue;
   1.175 @@ -517,22 +508,8 @@ static int netif_poll(struct net_device 
   1.176  static int network_close(struct net_device *dev)
   1.177  {
   1.178      struct net_private *np = dev->priv;
   1.179 -
   1.180 +    np->user_state = UST_CLOSED;
   1.181      netif_stop_queue(np->dev);
   1.182 -
   1.183 -    np->state = NETIF_STATE_CONNECTED;
   1.184 -
   1.185 -    /* XXX We need to properly disconnect via the domain controller. */
   1.186 -    while ( /*(np->rx_resp_cons != np->rx->req_prod) ||*/
   1.187 -            (np->tx_resp_cons != np->tx->req_prod) )
   1.188 -    {
   1.189 -        barrier();
   1.190 -        current->state = TASK_INTERRUPTIBLE;
   1.191 -        schedule_timeout(1);
   1.192 -    }
   1.193 -
   1.194 -    MOD_DEC_USE_COUNT;
   1.195 -
   1.196      return 0;
   1.197  }
   1.198  
   1.199 @@ -544,7 +521,8 @@ static struct net_device_stats *network_
   1.200  }
   1.201  
   1.202  
   1.203 -static void network_reconnect(struct net_device *dev, netif_fe_interface_status_changed_t *status)
   1.204 +static void network_connect(struct net_device *dev,
   1.205 +                            netif_fe_interface_status_changed_t *status)
   1.206  {
   1.207      struct net_private *np;
   1.208      int i, requeue_idx;
   1.209 @@ -576,8 +554,10 @@ static void network_reconnect(struct net
   1.210       * to avoid this but maybe it doesn't matter so much given the
   1.211       * interface has been down.
   1.212       */
   1.213 -    for( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ ){
   1.214 -            if( (unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET ) {
   1.215 +    for ( requeue_idx = 0, i = 1; i <= NETIF_TX_RING_SIZE; i++ )
   1.216 +    {
   1.217 +            if ( (unsigned long)np->tx_skbs[i] >= __PAGE_OFFSET )
   1.218 +            {
   1.219                  struct sk_buff *skb = np->tx_skbs[i];
   1.220                  
   1.221                  tx = &np->tx->ring[requeue_idx++].req;
   1.222 @@ -605,15 +585,12 @@ static void network_reconnect(struct net
   1.223       * domain a kick because we've probably just requeued some
   1.224       * packets.
   1.225       */
   1.226 -    netif_carrier_on(dev);
   1.227 -    netif_start_queue(dev);
   1.228 -    np->state = NETIF_STATE_ACTIVE;
   1.229 -
   1.230 +    np->backend_state = BEST_CONNECTED;
   1.231      notify_via_evtchn(status->evtchn);  
   1.232 -
   1.233      network_tx_buf_gc(dev);
   1.234  
   1.235 -    printk(KERN_INFO "Recovery completed\n");
   1.236 +    if ( np->user_state == UST_OPEN )
   1.237 +        netif_start_queue(dev);
   1.238  
   1.239      spin_unlock(&np->tx_lock);
   1.240      spin_unlock_irq(&np->rx_lock);
   1.241 @@ -644,14 +621,14 @@ static void netif_status_change(netif_fe
   1.242      {
   1.243      case NETIF_INTERFACE_STATUS_DESTROYED:
   1.244          printk(KERN_WARNING "Unexpected netif-DESTROYED message in state %d\n",
   1.245 -               np->state);
   1.246 +               np->backend_state);
   1.247          break;
   1.248  
   1.249      case NETIF_INTERFACE_STATUS_DISCONNECTED:
   1.250 -        if ( np->state != NETIF_STATE_CLOSED )
   1.251 +        if ( np->backend_state != BEST_CLOSED )
   1.252          {
   1.253              printk(KERN_WARNING "Unexpected netif-DISCONNECTED message"
   1.254 -                   " in state %d\n", np->state);
   1.255 +                   " in state %d\n", np->backend_state);
   1.256  	    printk(KERN_INFO "Attempting to reconnect network interface\n");
   1.257  
   1.258              /* Begin interface recovery.
   1.259 @@ -672,8 +649,7 @@ static void netif_status_change(netif_fe
   1.260              spin_lock_irq(&np->tx_lock);
   1.261              spin_lock(&np->rx_lock);
   1.262              netif_stop_queue(dev);
   1.263 -            netif_carrier_off(dev);
   1.264 -            np->state  = NETIF_STATE_DISCONNECTED;
   1.265 +            np->backend_state = BEST_DISCONNECTED;
   1.266              spin_unlock(&np->rx_lock);
   1.267              spin_unlock_irq(&np->tx_lock);
   1.268  
   1.269 @@ -689,7 +665,7 @@ static void netif_status_change(netif_fe
   1.270          np->rx = (netif_rx_interface_t *)__get_free_page(GFP_KERNEL);
   1.271          memset(np->tx, 0, PAGE_SIZE);
   1.272          memset(np->rx, 0, PAGE_SIZE);
   1.273 -        np->state  = NETIF_STATE_DISCONNECTED;
   1.274 +        np->backend_state = BEST_DISCONNECTED;
   1.275  
   1.276          /* Construct an interface-CONNECT message for the domain controller. */
   1.277          cmsg.type      = CMSG_NETIF_FE;
   1.278 @@ -705,18 +681,16 @@ static void netif_status_change(netif_fe
   1.279          break;
   1.280  
   1.281      case NETIF_INTERFACE_STATUS_CONNECTED:
   1.282 -        if ( np->state == NETIF_STATE_CLOSED ){
   1.283 +        if ( np->backend_state == BEST_CLOSED )
   1.284 +        {
   1.285              printk(KERN_WARNING "Unexpected netif-CONNECTED message"
   1.286 -                   " in state %d\n", np->state);
   1.287 +                   " in state %d\n", np->backend_state);
   1.288              break;
   1.289          }
   1.290  
   1.291          memcpy(dev->dev_addr, status->mac, ETH_ALEN);
   1.292  
   1.293 -        if ( netif_carrier_ok(dev) )
   1.294 -            np->state = NETIF_STATE_CONNECTED;
   1.295 -        else
   1.296 -            network_reconnect(dev, status);
   1.297 +        network_connect(dev, status);
   1.298  
   1.299          np->evtchn = status->evtchn;
   1.300          np->irq = bind_evtchn_to_irq(np->evtchn);
   1.301 @@ -740,20 +714,31 @@ static void netif_status_change(netif_fe
   1.302   */
   1.303  static int create_netdev(int handle, struct net_device **val)
   1.304  {
   1.305 -    int err = 0;
   1.306 +    int i, err = 0;
   1.307      struct net_device *dev = NULL;
   1.308      struct net_private *np = NULL;
   1.309  
   1.310 -    dev = alloc_etherdev(sizeof(struct net_private));
   1.311 -    if (!dev){
   1.312 +    if ( (dev = alloc_etherdev(sizeof(struct net_private))) == NULL )
   1.313 +    {
   1.314          printk(KERN_WARNING "%s> alloc_etherdev failed.\n", __FUNCTION__);
   1.315          err = -ENOMEM;
   1.316          goto exit;
   1.317      }
   1.318 -    np         = dev->priv;
   1.319 -    np->state  = NETIF_STATE_CLOSED;
   1.320 -    np->handle = handle;
   1.321 +
   1.322 +    np                = dev->priv;
   1.323 +    np->backend_state = BEST_CLOSED;
   1.324 +    np->user_state    = UST_CLOSED;
   1.325 +    np->handle        = handle;
   1.326      
   1.327 +    spin_lock_init(&np->tx_lock);
   1.328 +    spin_lock_init(&np->rx_lock);
   1.329 +
   1.330 +    /* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
   1.331 +    for ( i = 0; i <= NETIF_TX_RING_SIZE; i++ )
   1.332 +        np->tx_skbs[i] = (void *)(i+1);
   1.333 +    for ( i = 0; i <= NETIF_RX_RING_SIZE; i++ )
   1.334 +        np->rx_skbs[i] = (void *)(i+1);
   1.335 +
   1.336      dev->open            = network_open;
   1.337      dev->hard_start_xmit = network_start_xmit;
   1.338      dev->stop            = network_close;
   1.339 @@ -761,19 +746,19 @@ static int create_netdev(int handle, str
   1.340      dev->poll            = netif_poll;
   1.341      dev->weight          = 64;
   1.342      
   1.343 -    err = register_netdev(dev);
   1.344 -    if (err){
   1.345 +    if ( (err = register_netdev(dev)) != 0 )
   1.346 +    {
   1.347          printk(KERN_WARNING "%s> register_netdev err=%d\n", __FUNCTION__, err);
   1.348          goto exit;
   1.349      }
   1.350      np->dev = dev;
   1.351      list_add(&np->list, &dev_list);
   1.352 +
   1.353    exit:
   1.354 -    if(err){
   1.355 -        if(dev) kfree(dev);
   1.356 -        dev = NULL;
   1.357 -    }
   1.358 -    if(val) *val = dev;
   1.359 +    if ( (err != 0) && (dev != NULL ) )
   1.360 +        kfree(dev);
   1.361 +    else if ( val != NULL )
   1.362 +        *val = dev;
   1.363      return err;
   1.364  }
   1.365  
   1.366 @@ -790,9 +775,10 @@ static void netif_driver_status_change(
   1.367      netctrl.interface_n = status->nr_interfaces;
   1.368      netctrl.connected_n = 0;
   1.369  
   1.370 -    for(i = 0; i < netctrl.interface_n; i++){
   1.371 -        err = create_netdev(i, NULL);
   1.372 -        if(err){
   1.373 +    for ( i = 0; i < netctrl.interface_n; i++ )
   1.374 +    {
   1.375 +        if ( (err = create_netdev(i, NULL)) != 0 )
   1.376 +        {
   1.377              netctrl_err(err);
   1.378              break;
   1.379          }
   1.380 @@ -832,7 +818,7 @@ static void netif_ctrlif_rx(ctrl_msg_t *
   1.381  }
   1.382  
   1.383  
   1.384 -static int __init init_module(void)
   1.385 +static int __init netif_init(void)
   1.386  {
   1.387      ctrl_msg_t                       cmsg;
   1.388      netif_fe_driver_status_changed_t st;
   1.389 @@ -878,13 +864,4 @@ static int __init init_module(void)
   1.390      return err;
   1.391  }
   1.392  
   1.393 -
   1.394 -static void cleanup_module(void)
   1.395 -{
   1.396 -    /* XXX FIXME */
   1.397 -    BUG();
   1.398 -}
   1.399 -
   1.400 -
   1.401 -module_init(init_module);
   1.402 -module_exit(cleanup_module);
   1.403 +__initcall(netif_init);