/[dynamips]/upstream/dynamips-0.2.8-RC1/dev_c7200_pos.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.8-RC1/dev_c7200_pos.c

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

upstream/dynamips-0.2.7/dev_c7200_pos.c revision 10 by dpavlin, Sat Oct 6 16:29:14 2007 UTC upstream/dynamips-0.2.8-RC1/dev_c7200_pos.c revision 11 by dpavlin, Sat Oct 6 16:33:40 2007 UTC
# Line 6  Line 6 
6   *   - 0x95: PA-POS-OC3SMI   *   - 0x95: PA-POS-OC3SMI
7   *   - 0x96: PA-POS-OC3MM   *   - 0x96: PA-POS-OC3MM
8   *   *
9   * Just an experimentation (I don't have any PA-POS-OC3). It basically works,   * Just an experimentation (I don't have any PA-POS-OC3).
  * on NPE-400. There is something strange with the buffer addresses in TX ring,  
  * preventing this driver working with platforms using SRAM.  
10   */   */
11    
12  #include <stdio.h>  #include <stdio.h>
# Line 33  Line 31 
31  /* Debugging flags */  /* Debugging flags */
32  #define DEBUG_ACCESS    0  #define DEBUG_ACCESS    0
33  #define DEBUG_UNKNOWN   0  #define DEBUG_UNKNOWN   0
34  #define DEBUG_TRANSMIT  1  #define DEBUG_TRANSMIT  0
35  #define DEBUG_RECEIVE   1  #define DEBUG_RECEIVE   0
36    
37  /* PCI vendor/product codes */  /* PCI vendor/product codes */
38  #define POS_OC3_PCI_VENDOR_ID    0x10b5  #define POS_OC3_PCI_VENDOR_ID    0x10b5
# Line 69  struct tx_desc { Line 67  struct tx_desc {
67  struct pos_oc3_data {  struct pos_oc3_data {
68     char *name;     char *name;
69    
70       /* IRQ clearing count */
71       u_int irq_clearing_count;
72    
73       /* Control register #1 */
74       m_uint16_t ctrl_reg1;
75    
76       /* CRC size */
77       u_int crc_size;
78    
79     /* physical addresses for start and end of RX/TX rings */     /* physical addresses for start and end of RX/TX rings */
80     m_uint32_t rx_start,rx_end,tx_start,tx_end;     m_uint32_t rx_start,rx_end,tx_start,tx_end;
81        
# Line 290  static void *dev_pos_cs_access(cpu_gen_t Line 297  static void *dev_pos_cs_access(cpu_gen_t
297        case 0x30001c:        case 0x30001c:
298           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
299              *data = 0x00000FFF;              *data = 0x00000FFF;
300              pci_dev_clear_irq(d->vm,d->pci_dev);  
301                /* Add a delay before clearing the IRQ */
302                if (++d->irq_clearing_count == 20) {
303                   pci_dev_clear_irq(d->vm,d->pci_dev);
304                   d->irq_clearing_count = 0;
305                }
306           }               }    
307           break;           break;
308    
# Line 299  static void *dev_pos_cs_access(cpu_gen_t Line 311  static void *dev_pos_cs_access(cpu_gen_t
311              *data = 0x000007F;                    *data = 0x000007F;      
312           break;           break;
313    
314          case 0x300028:
315             if (op_type == MTS_READ) {
316                *data = d->ctrl_reg1;
317             } else {
318                d->ctrl_reg1 = *data;
319    
320                switch(*data) {
321                   case 0x06:
322                      d->crc_size = 2;
323                      break;
324                   case 0x07:
325                      d->crc_size = 4;
326                      break;
327                   default:
328                      d->crc_size = 2;
329                      cpu_log(cpu,d->cs_name,
330                              "unknown value 0x%4.4llx written in ctrl_reg1\n",
331                              *data);
332                }
333                cpu_log(cpu,d->cs_name,"CRC size set to 0x%4.4x\n",d->crc_size);
334             }
335             break;
336    
337  #if DEBUG_UNKNOWN  #if DEBUG_UNKNOWN
338        default:        default:
339           if (op_type == MTS_READ) {           if (op_type == MTS_READ) {
# Line 419  static void dev_pos_oc3_receive_pkt(stru Line 454  static void dev_pos_oc3_receive_pkt(stru
454    
455        /* We have finished if the complete packet has been stored */        /* We have finished if the complete packet has been stored */
456        if (tot_len == 0) {        if (tot_len == 0) {
457           rxdc->rdes[0] = (cp_len + 4);           rxdc->rdes[0] = (cp_len + d->crc_size);
458    
459           if (i != 0)           if (i != 0)
460              physmem_copy_u32_to_vm(d->vm,d->rx_current,rxdc->rdes[0]);              physmem_copy_u32_to_vm(d->vm,d->rx_current,rxdc->rdes[0]);
# Line 632  static void pci_pos_write(cpu_gen_t *cpu Line 667  static void pci_pos_write(cpu_gen_t *cpu
667   *   *
668   * Add a PA-POS port adapter into specified slot.   * Add a PA-POS port adapter into specified slot.
669   */   */
670  int dev_c7200_pa_pos_init(c7200_t *router,char *name,u_int pa_bay)  int dev_c7200_pa_pos_init(vm_instance_t *vm,struct cisco_card *card)
671  {  {
    struct pci_bus *pci_bus;  
672     struct pos_oc3_data *d;     struct pos_oc3_data *d;
673       u_int slot = card->slot_id;
674    
675     /* Allocate the private data structure for PA-POS-OC3 chip */     /* Allocate the private data structure for PA-POS-OC3 chip */
676     if (!(d = malloc(sizeof(*d)))) {     if (!(d = malloc(sizeof(*d)))) {
677        fprintf(stderr,"%s (PA-POS-OC3): out of memory\n",name);        vm_error(vm,"%s: out of memory\n",card->dev_name);
678        return(-1);        return(-1);
679     }     }
680    
681     memset(d,0,sizeof(*d));     memset(d,0,sizeof(*d));
682     d->name = name;     d->name = card->dev_name;
683     d->vm   = router->vm;     d->vm   = vm;
684    
685     /* Set the EEPROM */     /* Set the PCI bus */
686     c7200_pa_set_eeprom(router,pa_bay,cisco_eeprom_find_pa("PA-POS-OC3"));     card->pci_bus = vm->slots_pci_bus[slot];
687    
688     /* Get the appropriate PCI bus */     /* Set the EEPROM */
689     pci_bus = router->pa_bay[pa_bay].pci_map;     cisco_card_set_eeprom(vm,card,cisco_eeprom_find_pa("PA-POS-OC3"));
690       c7200_set_slot_eeprom(VM_C7200(vm),slot,&card->eeprom);
691    
692     /* Initialize RX device */     /* Initialize RX device */
693     d->rx_name = dyn_sprintf("%s_RX",name);     d->rx_name = dyn_sprintf("%s_RX",card->dev_name);
694     dev_init(&d->rx_dev);     dev_init(&d->rx_dev);
695     d->rx_dev.name      = d->rx_name;     d->rx_dev.name      = d->rx_name;
696     d->rx_dev.priv_data = d;     d->rx_dev.priv_data = d;
697     d->rx_dev.handler   = dev_pos_rx_access;     d->rx_dev.handler   = dev_pos_rx_access;
698    
699     /* Initialize TX device */     /* Initialize TX device */
700     d->tx_name = dyn_sprintf("%s_TX",name);     d->tx_name = dyn_sprintf("%s_TX",card->dev_name);
701     dev_init(&d->tx_dev);     dev_init(&d->tx_dev);
702     d->tx_dev.name      = d->tx_name;     d->tx_dev.name      = d->tx_name;
703     d->tx_dev.priv_data = d;     d->tx_dev.priv_data = d;
704     d->tx_dev.handler   = dev_pos_tx_access;     d->tx_dev.handler   = dev_pos_tx_access;
705    
706     /* Initialize CS device */     /* Initialize CS device */
707     d->cs_name = dyn_sprintf("%s_CS",name);     d->cs_name = dyn_sprintf("%s_CS",card->dev_name);
708     dev_init(&d->cs_dev);     dev_init(&d->cs_dev);
709     d->cs_dev.name      = d->cs_name;     d->cs_dev.name      = d->cs_name;
710     d->cs_dev.priv_data = d;     d->cs_dev.priv_data = d;
711     d->cs_dev.handler   = dev_pos_cs_access;     d->cs_dev.handler   = dev_pos_cs_access;
712    
713     /* Initialize PLX9060 for RX part */     /* Initialize PLX9060 for RX part */
714     d->rx_obj = dev_plx9060_init(d->vm,d->rx_name,pci_bus,0,&d->rx_dev);     d->rx_obj = dev_plx9060_init(vm,d->rx_name,card->pci_bus,0,&d->rx_dev);
715    
716     /* Initialize PLX9060 for TX part */     /* Initialize PLX9060 for TX part */
717     d->tx_obj = dev_plx9060_init(d->vm,d->tx_name,pci_bus,1,&d->tx_dev);     d->tx_obj = dev_plx9060_init(vm,d->tx_name,card->pci_bus,1,&d->tx_dev);
718    
719     /* Initialize PLX9060 for CS part (CS=card status, chip status, ... ?) */     /* Initialize PLX9060 for CS part (CS=card status, chip status, ... ?) */
720     d->cs_obj = dev_plx9060_init(d->vm,d->cs_name,pci_bus,2,&d->cs_dev);     d->cs_obj = dev_plx9060_init(vm,d->cs_name,card->pci_bus,2,&d->cs_dev);
721    
722     /* Unknown PCI device here (will be mapped at 0x30000) */     /* Unknown PCI device here (will be mapped at 0x30000) */
723     dev_init(&d->dev);     dev_init(&d->dev);
724     d->dev.name      = name;     d->dev.name      = card->dev_name;
725     d->dev.priv_data = d;     d->dev.priv_data = d;
726     d->dev.phys_len  = 0x10000;     d->dev.phys_len  = 0x10000;
727     d->dev.handler   = dev_pos_access;     d->dev.handler   = dev_pos_access;
728    
729     d->pci_dev = pci_dev_add(pci_bus,name,0,0,3,0,     d->pci_dev = pci_dev_add(card->pci_bus,card->dev_name,0,0,3,0,
730                              /*C7200_NETIO_IRQ,*/                              c7200_net_irq_for_slot_port(slot,0),
                             c7200_net_irq_for_slot_port(pa_bay,0),  
731                              d,NULL,pci_pos_read,pci_pos_write);                              d,NULL,pci_pos_read,pci_pos_write);
732    
733     /* Store device info into the router structure */     /* Store device info into the router structure */
734     return(c7200_pa_set_drvinfo(router,pa_bay,d));     card->drv_info = d;
735       return(0);
736  }  }
737    
738  /* Remove a PA-POS-OC3 from the specified slot */  /* Remove a PA-POS-OC3 from the specified slot */
739  int dev_c7200_pa_pos_shutdown(c7200_t *router,u_int pa_bay)  int dev_c7200_pa_pos_shutdown(vm_instance_t *vm,struct cisco_card *card)
740  {  {
741     struct c7200_pa_bay *bay;     struct pos_oc3_data *d = card->drv_info;
    struct pos_oc3_data *d;  
   
    if (!(bay = c7200_pa_get_info(router,pa_bay)))  
       return(-1);  
   
    d = bay->drv_info;  
742    
743     /* Remove the PA EEPROM */     /* Remove the PA EEPROM */
744     c7200_pa_unset_eeprom(router,pa_bay);     cisco_card_unset_eeprom(card);
745       c7200_set_slot_eeprom(VM_C7200(vm),card->slot_id,NULL);
746    
747     /* Remove the PCI device */     /* Remove the PCI device */
748     pci_dev_remove(d->pci_dev);     pci_dev_remove(d->pci_dev);
749    
750     /* Remove the PLX9060 chips */     /* Remove the PLX9060 chips */
751     vm_object_remove(d->vm,d->rx_obj);     vm_object_remove(vm,d->rx_obj);
752     vm_object_remove(d->vm,d->tx_obj);     vm_object_remove(vm,d->tx_obj);
753     vm_object_remove(d->vm,d->cs_obj);     vm_object_remove(vm,d->cs_obj);
754    
755     /* Remove the devices from the CPU address space */     /* Remove the devices from the CPU address space */
756     vm_unbind_device(router->vm,&d->rx_dev);     vm_unbind_device(vm,&d->rx_dev);
757     vm_unbind_device(router->vm,&d->tx_dev);     vm_unbind_device(vm,&d->tx_dev);
758     vm_unbind_device(router->vm,&d->cs_dev);     vm_unbind_device(vm,&d->cs_dev);
759    
760     vm_unbind_device(router->vm,&d->dev);     vm_unbind_device(vm,&d->dev);
761     cpu_group_rebuild_mts(router->vm->cpu_group);     cpu_group_rebuild_mts(vm->cpu_group);
762    
763     /* Free the device structure itself */     /* Free the device structure itself */
764     free(d);     free(d);
# Line 735  int dev_c7200_pa_pos_shutdown(c7200_t *r Line 766  int dev_c7200_pa_pos_shutdown(c7200_t *r
766  }  }
767    
768  /* Bind a Network IO descriptor to a specific port */  /* Bind a Network IO descriptor to a specific port */
769  int dev_c7200_pa_pos_set_nio(c7200_t *router,u_int pa_bay,u_int port_id,  int dev_c7200_pa_pos_set_nio(vm_instance_t *vm,struct cisco_card *card,
770                               netio_desc_t *nio)                               u_int port_id,netio_desc_t *nio)
771  {  {
772     struct pos_oc3_data *d;     struct pos_oc3_data *d = card->drv_info;
773    
774     if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))     if (!d || (port_id > 0))
775        return(-1);        return(-1);
776    
777     if (d->nio != NULL)     if (d->nio != NULL)
# Line 753  int dev_c7200_pa_pos_set_nio(c7200_t *ro Line 784  int dev_c7200_pa_pos_set_nio(c7200_t *ro
784  }  }
785    
786  /* Bind a Network IO descriptor to a specific port */  /* Bind a Network IO descriptor to a specific port */
787  int dev_c7200_pa_pos_unset_nio(c7200_t *router,u_int pa_bay,u_int port_id)  int dev_c7200_pa_pos_unset_nio(vm_instance_t *vm,struct cisco_card *card,
788                                   u_int port_id)
789  {  {
790     struct pos_oc3_data *d;     struct pos_oc3_data *d = card->drv_info;
791    
792     if ((port_id > 0) || !(d = c7200_pa_get_drvinfo(router,pa_bay)))     if (!d || (port_id > 0))
793        return(-1);        return(-1);
794    
795     if (d->nio) {     if (d->nio) {
# Line 769  int dev_c7200_pa_pos_unset_nio(c7200_t * Line 801  int dev_c7200_pa_pos_unset_nio(c7200_t *
801  }  }
802    
803  /* PA-POS-OC3 driver */  /* PA-POS-OC3 driver */
804  struct c7200_pa_driver dev_c7200_pa_pos_oc3_driver = {  struct cisco_card_driver dev_c7200_pa_pos_oc3_driver = {
805     "PA-POS-OC3", 1,     "PA-POS-OC3", 1, 0,
806     dev_c7200_pa_pos_init,     dev_c7200_pa_pos_init,
807     dev_c7200_pa_pos_shutdown,     dev_c7200_pa_pos_shutdown,
808       NULL,
809     dev_c7200_pa_pos_set_nio,     dev_c7200_pa_pos_set_nio,
810     dev_c7200_pa_pos_unset_nio,     dev_c7200_pa_pos_unset_nio,
811     NULL,     NULL,

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

  ViewVC Help
Powered by ViewVC 1.1.26