/[dynamips]/trunk/dev_mueslix.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/dev_mueslix.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

upstream/dynamips-0.2.7-RC1/dev_mueslix.c revision 7 by dpavlin, Sat Oct 6 16:23:47 2007 UTC upstream/dynamips-0.2.7-RC2/dev_mueslix.c revision 8 by dpavlin, Sat Oct 6 16:24:54 2007 UTC
# Line 96  Line 96 
96  #define MUESLIX_XYMEM_LEN     0x100  #define MUESLIX_XYMEM_LEN     0x100
97    
98  /* Maximum packet size */  /* Maximum packet size */
99  #define MUESLIX_MAX_PKT_SIZE  2048  #define MUESLIX_MAX_PKT_SIZE  18000
100    
101  /* Send up to 16 packets in a TX ring scan pass */  /* Send up to 16 packets in a TX ring scan pass */
102  #define MUESLIX_TXRING_PASS_COUNT  16  #define MUESLIX_TXRING_PASS_COUNT  16
# Line 109  Line 109 
109  #define MUESLIX_RXDESC_IGNORED    0x08000000  /* Ignored */  #define MUESLIX_RXDESC_IGNORED    0x08000000  /* Ignored */
110  #define MUESLIX_RXDESC_ABORT      0x04000000  /* Abort */  #define MUESLIX_RXDESC_ABORT      0x04000000  /* Abort */
111  #define MUESLIX_RXDESC_CRC        0x02000000  /* CRC error */  #define MUESLIX_RXDESC_CRC        0x02000000  /* CRC error */
112  #define MUESLIX_RXDESC_LEN_MASK   0xfff  #define MUESLIX_RXDESC_LEN_MASK   0xffff
113    
114  /* TX descriptors */  /* TX descriptors */
115  #define MUESLIX_TXDESC_OWN        0x80000000  /* Ownership */  #define MUESLIX_TXDESC_OWN        0x80000000  /* Ownership */
# Line 121  Line 121 
121  #define MUESLIX_TXDESC_PAD        0x00c00000  /* Sort of padding info ? */  #define MUESLIX_TXDESC_PAD        0x00c00000  /* Sort of padding info ? */
122  #define MUESLIX_TXDESC_PAD_SHIFT  22  #define MUESLIX_TXDESC_PAD_SHIFT  22
123    
124  #define MUESLIX_TXDESC_LEN_MASK   0xfff  #define MUESLIX_TXDESC_LEN_MASK   0xffff
125    
126  /* RX Descriptor */  /* RX Descriptor */
127  struct rx_desc {  struct rx_desc {
# Line 141  struct mueslix_channel { Line 141  struct mueslix_channel {
141     /* Channel ID */     /* Channel ID */
142     u_int id;     u_int id;
143    
    /* RX/TX status */  
    u_int rx_tx_status;  
   
144     /* Channel status (0=disabled) */     /* Channel status (0=disabled) */
145     u_int status;     u_int status;
146    
# Line 166  struct mueslix_channel { Line 163  struct mueslix_channel {
163  /* Mueslix Data */  /* Mueslix Data */
164  struct mueslix_data {  struct mueslix_data {
165     char *name;     char *name;
166      
167       /* Lock */
168       pthread_mutex_t lock;
169    
170       /* IRQ status and mask */
171       m_uint32_t irq_status,irq_mask;
172       u_int irq_clearing_count;
173    
174     /* TPU options */     /* TPU options */
175     m_uint32_t tpu_options;     m_uint32_t tpu_options;
176    
# Line 204  static m_uint32_t channel_offset[MUESLIX Line 208  static m_uint32_t channel_offset[MUESLIX
208     MUESLIX_CHANNEL2_OFFSET, MUESLIX_CHANNEL3_OFFSET,     MUESLIX_CHANNEL2_OFFSET, MUESLIX_CHANNEL3_OFFSET,
209  };  };
210    
211    /* Lock/Unlock primitives */
212    #define MUESLIX_LOCK(d)    pthread_mutex_lock(&(d)->lock)
213    #define MUESLIX_UNLOCK(d)  pthread_mutex_unlock(&(d)->lock)
214    
215  /* Log a Mueslix message */  /* Log a Mueslix message */
216  #define MUESLIX_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)  #define MUESLIX_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
217    
# Line 214  static inline int dev_mueslix_is_rx_tx_e Line 222  static inline int dev_mueslix_is_rx_tx_e
222     return((d->channel_enable_mask >> (id << 1)) & 0x03);     return((d->channel_enable_mask >> (id << 1)) & 0x03);
223  }  }
224    
225    /* Update IRQ status */
226    static inline void dev_mueslix_update_irq_status(struct mueslix_data *d)
227    {
228       if (d->irq_status & d->irq_mask)
229          pci_dev_trigger_irq(d->vm,d->pci_dev);
230       else {
231          if (++d->irq_clearing_count == 3) {
232             pci_dev_clear_irq(d->vm,d->pci_dev);
233             d->irq_clearing_count = 0;
234          }
235       }
236    }
237    
238  /*  /*
239   * Access to channel registers.   * Access to channel registers.
240   */   */
# Line 323  void *dev_mueslix_access(cpu_gen_t *cpu, Line 344  void *dev_mueslix_access(cpu_gen_t *cpu,
344                           u_int op_size,u_int op_type,m_uint64_t *data)                           u_int op_size,u_int op_type,m_uint64_t *data)
345  {  {
346     struct mueslix_data *d = dev->priv_data;     struct mueslix_data *d = dev->priv_data;
    struct mueslix_channel *channel;  
    m_uint32_t irq_status;  
347     int i;     int i;
348    
349  #if DEBUG_ACCESS >= 2  #if DEBUG_ACCESS >= 2
# Line 361  void *dev_mueslix_access(cpu_gen_t *cpu, Line 380  void *dev_mueslix_access(cpu_gen_t *cpu,
380        if ((offset >= channel_offset[i]) &&        if ((offset >= channel_offset[i]) &&
381            (offset < (channel_offset[i] + MUESLIX_CHANNEL_LEN)))            (offset < (channel_offset[i] + MUESLIX_CHANNEL_LEN)))
382     {     {
383          MUESLIX_LOCK(d);
384        dev_mueslix_chan_access(cpu,&d->channel[i],        dev_mueslix_chan_access(cpu,&d->channel[i],
385                                offset - channel_offset[i],                                offset - channel_offset[i],
386                                op_size,op_type,data);                                op_size,op_type,data);
387          MUESLIX_UNLOCK(d);
388        return NULL;        return NULL;
389     }     }
390    
391       MUESLIX_LOCK(d);
392    
393     /* Generic case */     /* Generic case */
394     switch(offset) {     switch(offset) {
395        /* this reg is accessed when an interrupt occurs */        /* this reg is accessed when an interrupt occurs */
396        case 0x0:        case 0x0:
397           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
398              irq_status = 0;              *data = d->irq_status;
   
             for(i=0;i<MUESLIX_NR_CHANNELS;i++) {  
                channel = &d->channel[i];  
   
                if ((dev_mueslix_is_rx_tx_enabled(d,i) & MUESLIX_TX_ENABLE) &&  
                    (channel->rx_tx_status & MUESLIX_CHANNEL_STATUS_RX))  
                   irq_status |= MUESLIX_RX_IRQ << i;  
   
                if ((dev_mueslix_is_rx_tx_enabled(d,i) & MUESLIX_TX_ENABLE) &&  
                    (channel->rx_tx_status & MUESLIX_CHANNEL_STATUS_TX))  
                   irq_status |= MUESLIX_TX_IRQ << i;  
             }  
   
             /*  
              * Hack: we re-trigger an interrupt here. This was necessary  
              * because the Mueslix driver was not working properly with  
              * a C3620 platform.  
              */  
             if (irq_status)  
                pci_dev_trigger_irq(d->vm,d->pci_dev);    
   
             *data = irq_status;  
399           } else {           } else {
400              for(i=0;i<MUESLIX_NR_CHANNELS;i++) {              d->irq_status &= ~(*data);
401                 channel = &d->channel[i];              dev_mueslix_update_irq_status(d);
                channel->rx_tx_status = 0;  
             }  
402           }           }
403           break;           break;
404    
405        /* maybe interrupt mask */        /* Maybe interrupt mask */
406        case 0x10:        case 0x10:
407           if (op_type == MTS_READ)           if (op_type == MTS_READ) {
408              *data = 0x2FF;              *data = d->irq_mask;
409             } else {
410                d->irq_mask = *data;
411                dev_mueslix_update_irq_status(d);
412             }
413           break;           break;
414    
415        case 0x14:        case 0x14:
# Line 486  void *dev_mueslix_access(cpu_gen_t *cpu, Line 489  void *dev_mueslix_access(cpu_gen_t *cpu,
489  #endif  #endif
490     }     }
491    
492       MUESLIX_UNLOCK(d);
493     return NULL;     return NULL;
494  }  }
495    
# Line 654  static void dev_mueslix_receive_pkt(stru Line 658  static void dev_mueslix_receive_pkt(stru
658     /* Indicate that we have a frame ready (XXX something to do ?) */     /* Indicate that we have a frame ready (XXX something to do ?) */
659    
660     /* Generate IRQ on CPU */     /* Generate IRQ on CPU */
661     channel->rx_tx_status |= MUESLIX_CHANNEL_STATUS_RX;     d->irq_status |= MUESLIX_RX_IRQ << channel->id;
662     pci_dev_trigger_irq(d->vm,d->pci_dev);     dev_mueslix_update_irq_status(d);
663  }  }
664    
665  /* Handle the Mueslix RX ring of the specified channel */  /* Handle the Mueslix RX ring of the specified channel */
666  static int dev_mueslix_handle_rxring(netio_desc_t *nio,  static int dev_mueslix_handle_rxring(netio_desc_t *nio,
667                                       u_char *pkt,ssize_t pkt_len,                                       u_char *pkt,ssize_t pkt_len,
668                                       struct mueslix_channel *channel)                                       struct mueslix_channel *channel)
669  {  {  
 #if DEBUG_RECEIVE  
670     struct mueslix_data *d = channel->parent;     struct mueslix_data *d = channel->parent;
671    
672    #if DEBUG_RECEIVE
673     MUESLIX_LOG(d,"channel %u: receiving a packet of %d bytes\n",     MUESLIX_LOG(d,"channel %u: receiving a packet of %d bytes\n",
674                 channel->id,pkt_len);                 channel->id,pkt_len);
675     mem_dump(log_file,pkt,pkt_len);     mem_dump(log_file,pkt,pkt_len);
676  #endif  #endif
677    
678     dev_mueslix_receive_pkt(channel,pkt,pkt_len);     MUESLIX_LOCK(d);
679       if (dev_mueslix_is_rx_tx_enabled(d,channel->id) & MUESLIX_RX_ENABLE)
680          dev_mueslix_receive_pkt(channel,pkt,pkt_len);
681       MUESLIX_UNLOCK(d);
682     return(TRUE);     return(TRUE);
683  }  }
684    
# Line 809  static int dev_mueslix_handle_txring_sin Line 816  static int dev_mueslix_handle_txring_sin
816     physmem_copy_u32_to_vm(d->vm,tx_start,0);     physmem_copy_u32_to_vm(d->vm,tx_start,0);
817    
818     /* Interrupt on completion ? */     /* Interrupt on completion ? */
819     channel->rx_tx_status |= MUESLIX_CHANNEL_STATUS_TX;     d->irq_status |= MUESLIX_TX_IRQ << channel->id;
820     pci_dev_trigger_irq(d->vm,d->pci_dev);       dev_mueslix_update_irq_status(d);
821     return(TRUE);     return(TRUE);
822  }  }
823    
824  /* Handle the TX ring of a specific channel */  /* Handle the TX ring of a specific channel */
825  static int dev_mueslix_handle_txring(struct mueslix_channel *channel)  static int dev_mueslix_handle_txring(struct mueslix_channel *channel)
826  {  {
827     int i;     struct mueslix_data *d = channel->parent;
828       int res,i;
829    
830     for(i=0;i<MUESLIX_TXRING_PASS_COUNT;i++)     if (!dev_mueslix_is_rx_tx_enabled(d,channel->id) & MUESLIX_TX_ENABLE)
831        if (!dev_mueslix_handle_txring_single(channel))        return(FALSE);
832    
833       for(i=0;i<MUESLIX_TXRING_PASS_COUNT;i++) {
834          MUESLIX_LOCK(d);
835          res = dev_mueslix_handle_txring_single(channel);
836          MUESLIX_UNLOCK(d);
837        
838          if (!res)
839           break;           break;
840       }
841    
842     return(TRUE);     return(TRUE);
843  }  }
# Line 873  dev_mueslix_init(vm_instance_t *vm,char Line 889  dev_mueslix_init(vm_instance_t *vm,char
889     }     }
890    
891     memset(d,0,sizeof(*d));     memset(d,0,sizeof(*d));
892       pthread_mutex_init(&d->lock,NULL);
893     d->chip_mode = chip_mode;     d->chip_mode = chip_mode;
894    
895     for(i=0;i<MUESLIX_NR_CHANNELS;i++)     for(i=0;i<MUESLIX_NR_CHANNELS;i++)

Legend:
Removed from v.7  
changed lines
  Added in v.8

  ViewVC Help
Powered by ViewVC 1.1.26