/[dynamips]/upstream/dynamips-0.2.7-RC2/dev_am79c971.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 /upstream/dynamips-0.2.7-RC2/dev_am79c971.c

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

upstream/dynamips-0.2.7-RC1/dev_am79c971.c revision 7 by dpavlin, Sat Oct 6 16:23:47 2007 UTC upstream/dynamips-0.2.7-RC2/dev_am79c971.c revision 8 by dpavlin, Sat Oct 6 16:24:54 2007 UTC
# Line 126  struct tx_desc { Line 126  struct tx_desc {
126  struct am79c971_data {  struct am79c971_data {
127     char *name;     char *name;
128    
129       /* Lock */
130       pthread_mutex_t lock;
131      
132     /* Interface type (10baseT or 100baseTX) */     /* Interface type (10baseT or 100baseTX) */
133     int type;     int type;
134    
135       /* RX/TX clearing count */
136       int rx_tx_clear_count;
137    
138     /* Current RAP (Register Address Pointer) value */     /* Current RAP (Register Address Pointer) value */
139     m_uint8_t rap;     m_uint8_t rap;
140    
# Line 172  struct am79c971_data { Line 178  struct am79c971_data {
178  /* Log an am79c971 message */  /* Log an am79c971 message */
179  #define AM79C971_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)  #define AM79C971_LOG(d,msg...) vm_log((d)->vm,(d)->name,msg)
180    
181    /* Lock/Unlock primitives */
182    #define AM79C971_LOCK(d)    pthread_mutex_lock(&(d)->lock)
183    #define AM79C971_UNLOCK(d)  pthread_mutex_unlock(&(d)->lock)
184    
185  static m_uint16_t mii_reg_values[32] = {  static m_uint16_t mii_reg_values[32] = {
186     0x1000, 0x782D, 0x2000, 0x5C01, 0x01E1, 0x0000, 0x0000, 0x0000,     0x1000, 0x782D, 0x0013, 0x78E2, 0x01E1, 0xC9E1, 0x000F, 0x2001,
187       0x0000, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF,
188       0x0104, 0x4780, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
189       0x0000, 0x0000, 0x00C8, 0x0000, 0xFFFF, 0x0000, 0x0000, 0x0000,
190    
191    #if 0
192       0x1000, 0x782D, 0x0013, 0x78e2, 0x01E1, 0xC9E1, 0x0000, 0x0000,
193     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
194     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x8060,     0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x8060,
195     0x8020, 0x0820, 0x0000, 0x3800, 0xA3B9, 0x0000, 0x0000, 0x0000,     0x8023, 0x0820, 0x0000, 0x3800, 0xA3B9, 0x0000, 0x0000, 0x0000,
196    #endif
197  };  };
198    
199  /* Read a MII register */  /* Read a MII register */
# Line 203  static inline int am79c971_handle_mac_ad Line 219  static inline int am79c971_handle_mac_ad
219  {  {
220     n_eth_hdr_t *hdr = (n_eth_hdr_t *)pkt;     n_eth_hdr_t *hdr = (n_eth_hdr_t *)pkt;
221    
222     /* Accept systematically frames if we are running is promiscuous mode */     /* Accept systematically frames if we are running in promiscuous mode */
223     if (d->csr[15] & AM79C971_CSR15_PROM)     if (d->csr[15] & AM79C971_CSR15_PROM)
224        return(TRUE);        return(TRUE);
225    
# Line 219  static inline int am79c971_handle_mac_ad Line 235  static inline int am79c971_handle_mac_ad
235  }  }
236    
237  /* Update the Interrupt Flag bit of csr0 */  /* Update the Interrupt Flag bit of csr0 */
238  static void am79c971_update_intr_flag(struct am79c971_data *d)  static void am79c971_update_irq_status(struct am79c971_data *d)
239  {  {
240     m_uint32_t mask;     m_uint32_t mask;
241    
242     mask = d->csr[3] & AM79C971_CSR3_IM_MASK;     /* Bits set in CR3 disable the specified interrupts */
243       mask = AM79C971_CSR3_IM_MASK & ~(d->csr[3] & AM79C971_CSR3_IM_MASK);
244        
245     if (d->csr[0] & mask)     if (d->csr[0] & mask)
246        d->csr[0] |= AM79C971_CSR0_INTR;        d->csr[0] |= AM79C971_CSR0_INTR;
247  }     else
248          d->csr[0] &= ~AM79C971_CSR0_INTR;
249    
250  /* Trigger an interrupt */     if ((d->csr[0] & (AM79C971_CSR0_INTR|AM79C971_CSR0_IENA)) ==
251  static int am79c971_trigger_irq(struct am79c971_data *d)         (AM79C971_CSR0_INTR|AM79C971_CSR0_IENA))
252  {     {
    if (d->csr[0] & (AM79C971_CSR0_INTR|AM79C971_CSR0_IENA)) {  
253        pci_dev_trigger_irq(d->vm,d->pci_dev);        pci_dev_trigger_irq(d->vm,d->pci_dev);
254        return(TRUE);     } else {
255          pci_dev_clear_irq(d->vm,d->pci_dev);
256     }     }
   
    return(FALSE);  
257  }  }
258    
259  /* Update RX/TX ON bits of csr0 */  /* Update RX/TX ON bits of csr0 */
# Line 325  static int am79c971_fetch_init_block(str Line 341  static int am79c971_fetch_init_block(str
341     /* Update RX/TX ON bits of csr0 since csr15 has been modified */     /* Update RX/TX ON bits of csr0 since csr15 has been modified */
342     am79c971_update_rx_tx_on_bits(d);     am79c971_update_rx_tx_on_bits(d);
343     AM79C971_LOG(d,"CSR0 = 0x%4.4x\n",d->csr[0]);     AM79C971_LOG(d,"CSR0 = 0x%4.4x\n",d->csr[0]);
   
    am79c971_update_intr_flag(d);  
   
    if (am79c971_trigger_irq(d))  
       AM79C971_LOG(d,"triggering IDON interrupt\n");  
   
344     return(0);     return(0);
345  }  }
346    
# Line 362  static void am79c971_rdp_access(cpu_gen_ Line 372  static void am79c971_rdp_access(cpu_gen_
372                 //AM79C971_LOG(d,"stopping interface!\n");                 //AM79C971_LOG(d,"stopping interface!\n");
373                 d->csr[0] = AM79C971_CSR0_STOP;                 d->csr[0] = AM79C971_CSR0_STOP;
374                 d->tx_pos = d->rx_pos = 0;                 d->tx_pos = d->rx_pos = 0;
375                   am79c971_update_irq_status(d);
376                 break;                 break;
377              }              }
378                            
379              /* These bits are cleared when set to 1 */              /* These bits are cleared when set to 1 */
380              mask  = AM79C971_CSR0_BABL | AM79C971_CSR0_CERR;              mask  = AM79C971_CSR0_BABL | AM79C971_CSR0_CERR;
381              mask |= AM79C971_CSR0_MISS | AM79C971_CSR0_MERR;              mask |= AM79C971_CSR0_MISS | AM79C971_CSR0_MERR;
             mask |= AM79C971_CSR0_RINT | AM79C971_CSR0_TINT;  
382              mask |= AM79C971_CSR0_IDON;              mask |= AM79C971_CSR0_IDON;
383    
384                if (++d->rx_tx_clear_count == 3) {
385                   mask |= AM79C971_CSR0_RINT | AM79C971_CSR0_TINT;
386                   d->rx_tx_clear_count = 0;
387                }
388    
389              d->csr[0] &= ~(*data & mask);              d->csr[0] &= ~(*data & mask);
390    
391              /* Save the Interrupt Enable bit */              /* Save the Interrupt Enable bit */
# Line 389  static void am79c971_rdp_access(cpu_gen_ Line 405  static void am79c971_rdp_access(cpu_gen_
405                 d->csr[0] &= ~AM79C971_CSR0_STOP;                 d->csr[0] &= ~AM79C971_CSR0_STOP;
406                 am79c971_update_rx_tx_on_bits(d);                 am79c971_update_rx_tx_on_bits(d);
407              }              }
408    
409                /* Update IRQ status */
410                am79c971_update_irq_status(d);
411           }           }
412           break;           break;
413    
# Line 400  static void am79c971_rdp_access(cpu_gen_ Line 419  static void am79c971_rdp_access(cpu_gen_
419           } else {           } else {
420              *data = (d->tx_l2len << 12) | (d->rx_l2len << 8);              *data = (d->tx_l2len << 12) | (d->rx_l2len << 8);
421           }           }
422           break;           break;            
423    
424        case 15:  /* CSR15: Mode */        case 15:  /* CSR15: Mode */
425           if (op_type == MTS_WRITE) {           if (op_type == MTS_WRITE) {
# Line 512  void *dev_am79c971_access(cpu_gen_t *cpu Line 531  void *dev_am79c971_access(cpu_gen_t *cpu
531     }     }
532  #endif  #endif
533    
534       AM79C971_LOCK(d);
535    
536     switch(offset) {     switch(offset) {
537        case 0x14:  /* RAP (Register Address Pointer) */        case 0x14:  /* RAP (Register Address Pointer) */
538           if (op_type == MTS_WRITE) {           if (op_type == MTS_WRITE) {
# Line 530  void *dev_am79c971_access(cpu_gen_t *cpu Line 551  void *dev_am79c971_access(cpu_gen_t *cpu
551           break;           break;
552     }     }
553    
554       AM79C971_UNLOCK(d);
555     return NULL;     return NULL;
556  }  }
557    
# Line 618  static int am79c971_receive_pkt(struct a Line 640  static int am79c971_receive_pkt(struct a
640     u_char *pkt_ptr = pkt;     u_char *pkt_ptr = pkt;
641     m_uint8_t sw_style;     m_uint8_t sw_style;
642     int i;     int i;
643      
644     /* Truncate the packet if it is too big */     /* Truncate the packet if it is too big */
645     pkt_len = m_min(pkt_len,AM79C971_MAX_PKT_SIZE);     pkt_len = m_min(pkt_len,AM79C971_MAX_PKT_SIZE);
646    
# Line 700  static int am79c971_receive_pkt(struct a Line 722  static int am79c971_receive_pkt(struct a
722     physmem_copy_u32_to_vm(d->vm,rx_start+4,rxd0.rmd[1]);     physmem_copy_u32_to_vm(d->vm,rx_start+4,rxd0.rmd[1]);
723    
724     d->csr[0] |= AM79C971_CSR0_RINT;     d->csr[0] |= AM79C971_CSR0_RINT;
725     am79c971_update_intr_flag(d);     am79c971_update_irq_status(d);
    am79c971_trigger_irq(d);  
726     return(TRUE);     return(TRUE);
727  }  }
728    
# Line 724  static int am79c971_handle_rxring(netio_ Line 745  static int am79c971_handle_rxring(netio_
745     mem_dump(log_file,pkt,pkt_len);     mem_dump(log_file,pkt,pkt_len);
746  #endif  #endif
747    
748       AM79C971_LOCK(d);
749    
750     /*     /*
751      * Receive only multicast/broadcast trafic + unicast traffic      * Receive only multicast/broadcast trafic + unicast traffic
752      * for this virtual machine.      * for this virtual machine.
# Line 732  static int am79c971_handle_rxring(netio_ Line 755  static int am79c971_handle_rxring(netio_
755     if (am79c971_handle_mac_addr(d,pkt))     if (am79c971_handle_mac_addr(d,pkt))
756        am79c971_receive_pkt(d,pkt,pkt_len);        am79c971_receive_pkt(d,pkt,pkt_len);
757    
758       AM79C971_UNLOCK(d);
759     return(TRUE);     return(TRUE);
760  }  }
761    
# Line 825  static int am79c971_handle_txring_single Line 849  static int am79c971_handle_txring_single
849        /* Copy packet data */        /* Copy packet data */
850        clen = ~((ptxd->tmd[1] & AM79C971_TMD1_LEN) - 1);        clen = ~((ptxd->tmd[1] & AM79C971_TMD1_LEN) - 1);
851        clen &= AM79C971_TMD1_LEN;        clen &= AM79C971_TMD1_LEN;
852    
853        physmem_copy_from_vm(d->vm,pkt_ptr,ptxd->tmd[0],clen);        physmem_copy_from_vm(d->vm,pkt_ptr,ptxd->tmd[0],clen);
854    
855        pkt_ptr += clen;        pkt_ptr += clen;
# Line 871  static int am79c971_handle_txring_single Line 896  static int am79c971_handle_txring_single
896    
897     /* Generate TX interrupt */     /* Generate TX interrupt */
898     d->csr[0] |= AM79C971_CSR0_TINT;     d->csr[0] |= AM79C971_CSR0_TINT;
899     am79c971_update_intr_flag(d);     am79c971_update_irq_status(d);
    am79c971_trigger_irq(d);  
900     return(TRUE);     return(TRUE);
901  }  }
902    
# Line 881  static int am79c971_handle_txring(struct Line 905  static int am79c971_handle_txring(struct
905  {  {
906     int i;     int i;
907    
908       AM79C971_LOCK(d);
909    
910     for(i=0;i<AM79C971_TXRING_PASS_COUNT;i++)     for(i=0;i<AM79C971_TXRING_PASS_COUNT;i++)
911        if (!am79c971_handle_txring_single(d))        if (!am79c971_handle_txring_single(d))
912           break;           break;
913    
914       AM79C971_UNLOCK(d);
915     return(TRUE);     return(TRUE);
916  }  }
917    
# Line 957  dev_am79c971_init(vm_instance_t *vm,char Line 984  dev_am79c971_init(vm_instance_t *vm,char
984    
985     memset(d,0,sizeof(*d));     memset(d,0,sizeof(*d));
986     memcpy(d->mii_regs[0],mii_reg_values,sizeof(mii_reg_values));     memcpy(d->mii_regs[0],mii_reg_values,sizeof(mii_reg_values));
987       pthread_mutex_init(&d->lock,NULL);
988    
989     /* Add as PCI device */     /* Add as PCI device */
990     pci_dev = pci_dev_add(pci_bus,name,     pci_dev = pci_dev_add(pci_bus,name,

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

  ViewVC Help
Powered by ViewVC 1.1.26