/[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.8-RC1/dev_mueslix.c revision 11 by dpavlin, Sat Oct 6 16:33:40 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    
147       /* CRC control register */
148       u_int crc_ctrl_reg;
149    
150       /* CRC size */
151       u_int crc_size;
152    
153     /* NetIO descriptor */     /* NetIO descriptor */
154     netio_desc_t *nio;     netio_desc_t *nio;
155    
# Line 166  struct mueslix_channel { Line 169  struct mueslix_channel {
169  /* Mueslix Data */  /* Mueslix Data */
170  struct mueslix_data {  struct mueslix_data {
171     char *name;     char *name;
172      
173       /* Lock */
174       pthread_mutex_t lock;
175    
176       /* IRQ status and mask */
177       m_uint32_t irq_status,irq_mask;
178       u_int irq_clearing_count;
179    
180     /* TPU options */     /* TPU options */
181     m_uint32_t tpu_options;     m_uint32_t tpu_options;
182    
# Line 204  static m_uint32_t channel_offset[MUESLIX Line 214  static m_uint32_t channel_offset[MUESLIX
214     MUESLIX_CHANNEL2_OFFSET, MUESLIX_CHANNEL3_OFFSET,     MUESLIX_CHANNEL2_OFFSET, MUESLIX_CHANNEL3_OFFSET,
215  };  };
216    
217    /* Lock/Unlock primitives */
218    #define MUESLIX_LOCK(d)    pthread_mutex_lock(&(d)->lock)
219    #define MUESLIX_UNLOCK(d)  pthread_mutex_unlock(&(d)->lock)
220    
221  /* Log a Mueslix message */  /* Log a Mueslix message */
222  #define MUESLIX_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)  #define MUESLIX_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
223    
# Line 214  static inline int dev_mueslix_is_rx_tx_e Line 228  static inline int dev_mueslix_is_rx_tx_e
228     return((d->channel_enable_mask >> (id << 1)) & 0x03);     return((d->channel_enable_mask >> (id << 1)) & 0x03);
229  }  }
230    
231    /* Update IRQ status */
232    static inline void dev_mueslix_update_irq_status(struct mueslix_data *d)
233    {
234       if (d->irq_status & d->irq_mask)
235          pci_dev_trigger_irq(d->vm,d->pci_dev);
236       else {
237          if (++d->irq_clearing_count == 3) {
238             pci_dev_clear_irq(d->vm,d->pci_dev);
239             d->irq_clearing_count = 0;
240          }
241       }
242    }
243    
244  /*  /*
245   * Access to channel registers.   * Access to channel registers.
246   */   */
# Line 222  void dev_mueslix_chan_access(cpu_gen_t * Line 249  void dev_mueslix_chan_access(cpu_gen_t *
249                               m_uint64_t *data)                               m_uint64_t *data)
250  {  {
251     switch(offset) {     switch(offset) {
252          case 0x00: /* CRC control register ? */
253             if (op_type == MTS_READ) {
254                *data = channel->crc_ctrl_reg;
255             } else {
256                channel->crc_ctrl_reg = *data;
257                
258                switch(channel->crc_ctrl_reg) {
259                   case 0x08:
260                   case 0x0a:
261                      channel->crc_size = channel->crc_ctrl_reg - 0x06;
262                      break;
263    
264                   default:
265                      MUESLIX_LOG(channel->parent,"channel %u: unknown value "
266                                  "for CRC ctrl reg 0x%4.4x\n",
267                                  channel->id,channel->crc_ctrl_reg);
268    
269                      channel->crc_size = 2;
270                }
271                MUESLIX_LOG(channel->parent,
272                            "channel %u: CRC size set to 0x%4.4x\n",
273                            channel->id,channel->crc_size);
274             }
275             break;
276    
277        case 0x60: /* signals ? */        case 0x60: /* signals ? */
278           if ((op_type == MTS_READ) && (channel->nio != NULL))           if ((op_type == MTS_READ) && (channel->nio != NULL))
279              *data = 0xFFFFFFFF;              *data = 0xFFFFFFFF;
# Line 323  void *dev_mueslix_access(cpu_gen_t *cpu, Line 375  void *dev_mueslix_access(cpu_gen_t *cpu,
375                           u_int op_size,u_int op_type,m_uint64_t *data)                           u_int op_size,u_int op_type,m_uint64_t *data)
376  {  {
377     struct mueslix_data *d = dev->priv_data;     struct mueslix_data *d = dev->priv_data;
    struct mueslix_channel *channel;  
    m_uint32_t irq_status;  
378     int i;     int i;
379    
380  #if DEBUG_ACCESS >= 2  #if DEBUG_ACCESS >= 2
# Line 361  void *dev_mueslix_access(cpu_gen_t *cpu, Line 411  void *dev_mueslix_access(cpu_gen_t *cpu,
411        if ((offset >= channel_offset[i]) &&        if ((offset >= channel_offset[i]) &&
412            (offset < (channel_offset[i] + MUESLIX_CHANNEL_LEN)))            (offset < (channel_offset[i] + MUESLIX_CHANNEL_LEN)))
413     {     {
414          MUESLIX_LOCK(d);
415        dev_mueslix_chan_access(cpu,&d->channel[i],        dev_mueslix_chan_access(cpu,&d->channel[i],
416                                offset - channel_offset[i],                                offset - channel_offset[i],
417                                op_size,op_type,data);                                op_size,op_type,data);
418          MUESLIX_UNLOCK(d);
419        return NULL;        return NULL;
420     }     }
421    
422       MUESLIX_LOCK(d);
423    
424     /* Generic case */     /* Generic case */
425     switch(offset) {     switch(offset) {
426        /* this reg is accessed when an interrupt occurs */        /* this reg is accessed when an interrupt occurs */
427        case 0x0:        case 0x0:
428           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
429              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;  
430           } else {           } else {
431              for(i=0;i<MUESLIX_NR_CHANNELS;i++) {              d->irq_status &= ~(*data);
432                 channel = &d->channel[i];              dev_mueslix_update_irq_status(d);
                channel->rx_tx_status = 0;  
             }  
433           }           }
434           break;           break;
435    
436        /* maybe interrupt mask */        /* Maybe interrupt mask */
437        case 0x10:        case 0x10:
438           if (op_type == MTS_READ)           if (op_type == MTS_READ) {
439              *data = 0x2FF;              *data = d->irq_mask;
440             } else {
441                d->irq_mask = *data;
442                dev_mueslix_update_irq_status(d);
443             }
444           break;           break;
445    
446        case 0x14:        case 0x14:
# Line 486  void *dev_mueslix_access(cpu_gen_t *cpu, Line 520  void *dev_mueslix_access(cpu_gen_t *cpu,
520  #endif  #endif
521     }     }
522    
523       MUESLIX_UNLOCK(d);
524     return NULL;     return NULL;
525  }  }
526    
# Line 609  static void dev_mueslix_receive_pkt(stru Line 644  static void dev_mueslix_receive_pkt(stru
644        /* We have finished if the complete packet has been stored */        /* We have finished if the complete packet has been stored */
645        if (tot_len == 0) {        if (tot_len == 0) {
646           rxdc->rdes[0] = MUESLIX_RXDESC_LS;           rxdc->rdes[0] = MUESLIX_RXDESC_LS;
647           rxdc->rdes[0] |= cp_len;           rxdc->rdes[0] |= cp_len + channel->crc_size + 1;
648    
649           if (i != 0)           if (i != 0)
650              physmem_copy_u32_to_vm(d->vm,channel->rx_current,rxdc->rdes[0]);              physmem_copy_u32_to_vm(d->vm,channel->rx_current,rxdc->rdes[0]);
# Line 654  static void dev_mueslix_receive_pkt(stru Line 689  static void dev_mueslix_receive_pkt(stru
689     /* Indicate that we have a frame ready (XXX something to do ?) */     /* Indicate that we have a frame ready (XXX something to do ?) */
690    
691     /* Generate IRQ on CPU */     /* Generate IRQ on CPU */
692     channel->rx_tx_status |= MUESLIX_CHANNEL_STATUS_RX;     d->irq_status |= MUESLIX_RX_IRQ << channel->id;
693     pci_dev_trigger_irq(d->vm,d->pci_dev);     dev_mueslix_update_irq_status(d);
694  }  }
695    
696  /* Handle the Mueslix RX ring of the specified channel */  /* Handle the Mueslix RX ring of the specified channel */
697  static int dev_mueslix_handle_rxring(netio_desc_t *nio,  static int dev_mueslix_handle_rxring(netio_desc_t *nio,
698                                       u_char *pkt,ssize_t pkt_len,                                       u_char *pkt,ssize_t pkt_len,
699                                       struct mueslix_channel *channel)                                       struct mueslix_channel *channel)
700  {  {  
 #if DEBUG_RECEIVE  
701     struct mueslix_data *d = channel->parent;     struct mueslix_data *d = channel->parent;
702    
703    #if DEBUG_RECEIVE
704     MUESLIX_LOG(d,"channel %u: receiving a packet of %d bytes\n",     MUESLIX_LOG(d,"channel %u: receiving a packet of %d bytes\n",
705                 channel->id,pkt_len);                 channel->id,pkt_len);
706     mem_dump(log_file,pkt,pkt_len);     mem_dump(log_file,pkt,pkt_len);
707  #endif  #endif
708    
709     dev_mueslix_receive_pkt(channel,pkt,pkt_len);     MUESLIX_LOCK(d);
710       if (dev_mueslix_is_rx_tx_enabled(d,channel->id) & MUESLIX_RX_ENABLE)
711          dev_mueslix_receive_pkt(channel,pkt,pkt_len);
712       MUESLIX_UNLOCK(d);
713     return(TRUE);     return(TRUE);
714  }  }
715    
# Line 768  static int dev_mueslix_handle_txring_sin Line 806  static int dev_mueslix_handle_txring_sin
806        /* Be sure that we have length not null */        /* Be sure that we have length not null */
807        if (clen != 0) {        if (clen != 0) {
808           //printf("pkt_ptr = %p, ptxd->tdes[1] = 0x%x, clen = %d\n",           //printf("pkt_ptr = %p, ptxd->tdes[1] = 0x%x, clen = %d\n",
809           //pkt_ptr, ptxd->tdes[1], clen);           //       pkt_ptr, ptxd->tdes[1], clen);
810           physmem_copy_from_vm(d->vm,pkt_ptr,ptxd->tdes[1],clen);           physmem_copy_from_vm(d->vm,pkt_ptr,ptxd->tdes[1],clen);
811        }        }
812    
# Line 799  static int dev_mueslix_handle_txring_sin Line 837  static int dev_mueslix_handle_txring_sin
837    
838        pad = ptxd->tdes[0] & MUESLIX_TXDESC_PAD;        pad = ptxd->tdes[0] & MUESLIX_TXDESC_PAD;
839        pad >>= MUESLIX_TXDESC_PAD_SHIFT;        pad >>= MUESLIX_TXDESC_PAD_SHIFT;
840        tot_len += (pad - 1) & 0x03;        tot_len -= (4 - pad) & 0x03;
841    
842        /* send it on wire */        /* send it on wire */
843        netio_send(channel->nio,pkt,tot_len);        netio_send(channel->nio,pkt,tot_len);
844     }     }
# Line 809  static int dev_mueslix_handle_txring_sin Line 847  static int dev_mueslix_handle_txring_sin
847     physmem_copy_u32_to_vm(d->vm,tx_start,0);     physmem_copy_u32_to_vm(d->vm,tx_start,0);
848    
849     /* Interrupt on completion ? */     /* Interrupt on completion ? */
850     channel->rx_tx_status |= MUESLIX_CHANNEL_STATUS_TX;     d->irq_status |= MUESLIX_TX_IRQ << channel->id;
851     pci_dev_trigger_irq(d->vm,d->pci_dev);       dev_mueslix_update_irq_status(d);
852     return(TRUE);     return(TRUE);
853  }  }
854    
855  /* Handle the TX ring of a specific channel */  /* Handle the TX ring of a specific channel */
856  static int dev_mueslix_handle_txring(struct mueslix_channel *channel)  static int dev_mueslix_handle_txring(struct mueslix_channel *channel)
857  {  {
858     int i;     struct mueslix_data *d = channel->parent;
859       int res,i;
860    
861     for(i=0;i<MUESLIX_TXRING_PASS_COUNT;i++)     if (!dev_mueslix_is_rx_tx_enabled(d,channel->id) & MUESLIX_TX_ENABLE)
862        if (!dev_mueslix_handle_txring_single(channel))        return(FALSE);
863    
864       for(i=0;i<MUESLIX_TXRING_PASS_COUNT;i++) {
865          MUESLIX_LOCK(d);
866          res = dev_mueslix_handle_txring_single(channel);
867          MUESLIX_UNLOCK(d);
868        
869          if (!res)
870           break;           break;
871       }
872    
873     return(TRUE);     return(TRUE);
874  }  }
# Line 873  dev_mueslix_init(vm_instance_t *vm,char Line 920  dev_mueslix_init(vm_instance_t *vm,char
920     }     }
921    
922     memset(d,0,sizeof(*d));     memset(d,0,sizeof(*d));
923       pthread_mutex_init(&d->lock,NULL);
924     d->chip_mode = chip_mode;     d->chip_mode = chip_mode;
925    
926     for(i=0;i<MUESLIX_NR_CHANNELS;i++)     for(i=0;i<MUESLIX_NR_CHANNELS;i++) {
927        d->channel[i].id = i;        d->channel[i].id = i;
928          d->channel[i].parent = d;
929       }
930    
931     /* Add as PCI device */     /* Add as PCI device */
932     pci_dev = pci_dev_add(pci_bus,name,     pci_dev = pci_dev_add(pci_bus,name,
# Line 939  int dev_mueslix_set_nio(struct mueslix_d Line 989  int dev_mueslix_set_nio(struct mueslix_d
989    
990     /* define the new NIO */     /* define the new NIO */
991     channel->nio = nio;     channel->nio = nio;
    channel->parent = d;  
992     channel->tx_tid = ptask_add((ptask_callback)dev_mueslix_handle_txring,     channel->tx_tid = ptask_add((ptask_callback)dev_mueslix_handle_txring,
993                                 channel,NULL);                                 channel,NULL);
994     netio_rxl_add(nio,(netio_rx_handler_t)dev_mueslix_handle_rxring,     netio_rxl_add(nio,(netio_rx_handler_t)dev_mueslix_handle_rxring,

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

  ViewVC Help
Powered by ViewVC 1.1.26