lib_ocm.c

Go to the documentation of this file.
00001 /* #pragma ident "@(#)lib_ocm.c 1.43 10/26/09 EDT" */
00002 
00096 #include "edtinc.h"
00097 
00098 #include "edt_bitload.h"
00099 
00100 #include "edt_ocm.h"
00101 #include "edt_ocx.h"
00102 #include "edt_oc192.h"
00103 
00104 
00105 /**********************************
00106 * These functions work the same 
00107 * on both OCM and OC192
00108 **********************************/
00109 
00119 void
00120 edt_ocx_enable_framing_errors(EdtDev *edt_p, int state)
00121 
00122 {
00123 
00124     u_int mezzanine_offset = 0;
00125 
00126     if (edt_p->channel_no & 1)
00127     {
00128         mezzanine_offset = OFFSET_CH1_MEZ;
00129     }
00130 
00131     edt_reg_set_bitmask(edt_p, OCM_CH0_CNT_CTRL + mezzanine_offset,
00132         OCM_EN_ERROR_COUNT, state);
00133 
00134 }
00135 
00136 
00149 int 
00150 edt_ocx_get_framing_errors(EdtDev *edt_p, EdtOCXFrameErrors *err_p)
00151 
00152 {
00153     u_int mezzanine_offset = 0;
00154 
00155     if (edt_p->channel_no & 1)
00156     {
00157         mezzanine_offset = OFFSET_CH1_MEZ;
00158     }
00159     /* Assume frame counts are enabled */
00160 
00161     edt_reg_set_bitmask(edt_p, OCM_CH0_CNT_CTRL + mezzanine_offset , 
00162         OCM_ERROR_COUNT_HOLD, 1);
00163 
00164     err_p->b1_errors = edt_reg_read(edt_p, 
00165         OCM_CH0_B1_ERROR_CNT + mezzanine_offset);
00166     err_p->b1_error_mask = (u_char) edt_reg_read(edt_p, 
00167         OCM_CH0_B1_ERROR_MASK + mezzanine_offset);
00168     err_p->b2_errors = edt_reg_read(edt_p, 
00169         OCM_CH0_B2_ERROR_CNT + mezzanine_offset);
00170     err_p->m1_errors = edt_reg_read(edt_p, 
00171         OCM_CH0_M1_ERROR_CNT + mezzanine_offset);
00172     err_p->lof_errors = edt_reg_read(edt_p, 
00173         OCM_CH0_LOF_CNT + mezzanine_offset);
00174     err_p->frame_pattern_errors = edt_reg_read(edt_p, 
00175         OCM_CH0_FRM_PAT_CNT + mezzanine_offset);
00176     err_p->false_frame_errors = edt_reg_read(edt_p, 
00177         OCM_CH0_FALSE_FRM_CNT + mezzanine_offset);
00178 
00179     edt_reg_set_bitmask(edt_p, OCM_CH0_CNT_CTRL + mezzanine_offset , 
00180         OCM_ERROR_COUNT_HOLD, 0);
00181 
00182     return 0;
00183 }
00184 
00185 
00199 int
00200 edt_ocx_lock_local_clock(EdtDev *edt_p, int timeout)
00201 
00202 {
00203 
00204     FENTER("edt_ocx_lock_clocks");
00205 
00206     if (edt_wait_register_bits_high(edt_p, PCD_STAT, LOCAL_SYS_LOCK,timeout))
00207     {
00208         edt_msg(EDTLIB_MSG_FATAL,"\rBaseboard System clock not locked");
00209         return -1;
00210     }
00211 
00212     edt_msg(EDTLIB_MSG_INFO_1,"Local System clocks locked \n");
00213 
00214     return 0;
00215 
00216 }
00217 
00232 int
00233 edt_ocx_lock_channel_clock(EdtDev *edt_p, int channel, int timeout)
00234 
00235 {
00236     int base_offset;
00237 
00238     FENTER("edt_ocx_lock_clocks");
00239 
00240     base_offset = (channel & 1) ? OFFSET_CH1_BASE:0;
00241 
00242     if (edt_wait_register_bits_high (edt_p, OCM_CH0_ENABLE + base_offset,
00243         SYS_LOCK,timeout))
00244     {
00245         edt_msg(EDTLIB_MSG_FATAL,"\rMezzanine System clock not locked");
00246         return -1;
00247 
00248     }
00249 
00250     return 0;
00251 
00252 }
00253 
00268 int
00269 edt_msdv_load_default_mezzanine(EdtDev *edt_p, EdtOCConfig *cfg)
00270 
00271 {
00272     int rc = 0;
00273 
00274     char *bitname = "dvb_asi.bit";
00275 
00276     if (cfg->mezz_0)
00277         if (cfg->mezz_0[0])
00278             bitname = cfg->mezz_0;
00279 
00280     rc = edt_bitload(edt_p, NULL, bitname, BITLOAD_FLAGS_MEZZANINE, 0);
00281 
00282     return rc;
00283 }
00284 
00299 int
00300 edt_net10g_load_default_mezzanine(EdtDev *edt_p,EdtOCConfig *cfg)
00301 
00302 {
00303     int rc = 0;
00304 
00305     char *bitname = "net10g_5v_sdh.bit";
00306 
00307     FENTER("edt_net10g_load_default_mezzanine");
00308     if (cfg->mezz_0)
00309         if (cfg->mezz_0[0])
00310             bitname = cfg->mezz_0;
00311 
00312     rc = edt_bitload(edt_p, NULL, bitname, BITLOAD_FLAGS_MEZZANINE, 0);
00313 
00314     if (rc == 0)
00315     {
00316         bitname = "net10g_s3_cfg.bit";
00317 
00318         if (cfg->mezz_1)
00319             if (cfg->mezz_1[0])
00320                 bitname = cfg->mezz_1;
00321 
00322         rc = edt_bitload(edt_p, NULL, bitname, BITLOAD_FLAGS_MEZZANINE | BITLOAD_FLAGS_CH1, 0);
00323     }
00324 
00325     return rc;
00326 }
00327 
00328 /***************************************
00329 *
00330 * OCM specific functions
00331 * Most have equivalent OC192 functions
00332 *
00333 **************************************/
00334 
00345 int
00346 edt_ocm_lock_clocks(EdtDev *edt_p, int timeout)
00347 
00348 {
00349 
00350     if (edt_ocx_lock_local_clock(edt_p, timeout) ||
00351         edt_ocx_lock_channel_clock(edt_p, 0, timeout) ||
00352         edt_ocx_lock_channel_clock(edt_p, 1, timeout))
00353 
00354         return -1;
00355 
00356     edt_msg(EDTLIB_MSG_INFO_1,"All System clocks locked          \n");
00357 
00358     return 0;
00359 
00360 }
00361 
00362 
00374 const char *
00375 edt_ocm_mezz_filename(EdtDev *edt_p, EdtOCConfig *cfg)
00376 
00377 {
00378 
00379     char *target_bitfile;
00380 
00381     switch (cfg->line_rate) {
00382         case OC3_RATE:      
00383         case OC12_RATE:     
00384         case STM1_RATE:
00385         case STM4_RATE:
00386             target_bitfile="ocm12.bit";
00387             break;
00388 
00389         case STM16_RATE:            
00390         case OC48_RATE:     
00391             target_bitfile="ocm48.bit";
00392             break;
00393 
00394         case GIGE_RATE:
00395             target_bitfile="ethernet.bit";
00396             break;
00397 
00398         default:
00399             target_bitfile = NULL;
00400 
00401     }
00402 
00403     return target_bitfile;
00404 }
00405 
00423 int
00424 edt_ocm_load_default_mezzanine(EdtDev *edt_p, EdtOCConfig *cfg)
00425 
00426 {
00427 
00428     int rc = 0;
00429     int flags  = BITLOAD_FLAGS_OVR | BITLOAD_FLAGS_OCM;
00430     int rate = OC48_RATE;
00431 
00432     const char *bitname;
00433 
00434     if (edt_p->channel_no == 0)
00435         rate = (cfg->line_rate)?cfg->line_rate:OC48_RATE;
00436 
00437     if (cfg->mezz_0 && cfg->mezz_0[0])
00438         bitname = cfg->mezz_0;
00439     else
00440         bitname = edt_ocm_mezz_filename(edt_p, cfg);
00441 
00442     rc = edt_bitload(edt_p, NULL, bitname, flags, 0);
00443 
00444     if (rc == 0)
00445     {
00446         flags |= BITLOAD_FLAGS_CH1;
00447 
00448         if (cfg->mezz_1 && cfg->mezz_1[0])
00449             bitname = cfg->mezz_1;
00450         else
00451             bitname = edt_ocm_mezz_filename(edt_p, cfg);
00452 
00453         rc = edt_bitload(edt_p, NULL, bitname, flags, 0);
00454 
00455     }
00456 
00457     return rc;
00458 
00459 }
00460 
00473 int
00474 edt_ocm_speed_capable(int channel, EdtLineRate line_rate)
00475 
00476 {
00477     int rc = -1;
00478     switch (line_rate) {
00479         case STM1_RATE:
00480         case STM4_RATE:
00481         case OC3_RATE:      
00482         case OC12_RATE:     
00483         case GIGE_RATE:
00484         case STM16_RATE:            
00485         case OC48_RATE:     
00486         case OTU1_RATE:
00487             rc = 0;
00488             break;
00489 
00490         case GIG10E_RATE:
00491         case OTU2_RATE:
00492         case STM64_RATE:
00493         case OC192_RATE:
00494             rc =  -1;
00495             break;
00496 
00497         default:
00498             edt_msg(EDTLIB_MSG_FATAL,"Unknown bit rate %d\n", line_rate);
00499             rc =  -1;
00500 
00501     } 
00502     return rc;
00503 }
00504 
00505 
00506 
00520 int
00521 edt_ocm_has_mezz_bitfile(EdtDev *edt_p, const char *bitfile_name)
00522 
00523 {
00524     int channel = edt_p->channel_no & 1;
00525     char *ch_id;
00526     int rc;
00527 
00528     FENTER_S("edt_ocm_has_correct_bitfile",bitfile_name);
00529 
00530     if (channel == 0)
00531     {
00532         ch_id  = edt_p->bfd.mezz_name0;
00533     }
00534     else
00535     {
00536         ch_id  = edt_p->bfd.mezz_name1;
00537     }
00538 
00539     /* check correct bitfile for channel 0 */
00540     rc = strcmp(ch_id, bitfile_name);
00541 
00542     FRETURN_I("edt_ocm_has_correct_bitfile",rc);
00543 
00544     return rc;
00545 
00546 }
00560 int
00561 edt_ocm_set_clock_select(EdtDev *edt_p, EdtLineRate line_rate)
00562 
00563 {
00564     int channel = edt_p->channel_no & 1;
00565     int clk_select = CLK_SONET_SDH;
00566     int clk_val = OC3_STM1;
00567     int base_offset = 0;
00568     int mezzanine_offset = 0;
00569     int read_byte;
00570 
00571 
00572     FENTER_I("edt_ocm_set_clock_select", line_rate);
00573 
00574     switch (line_rate)
00575     {
00576     case OC3_RATE:          
00577     case STM1_RATE:
00578         clk_val = OC3_STM1;
00579         break;
00580 
00581     case OC12_RATE:      
00582     case STM4_RATE:
00583         clk_val = OC12_STM4;
00584         break;
00585 
00586     case STM16_RATE:        
00587     case OC48_RATE:         
00588         clk_val = OC48_STM16;
00589         break;
00590 
00591     case GIGE_RATE:
00592         clk_val = OC24;
00593         clk_select = CLK_GE | 0x4;
00594         break;
00595 
00596     case OTU1_RATE:
00597         /* set LIU for OC48, clk src to 166.62857 */
00598         clk_val = OC48_STM16;
00599         clk_select = CLK_FEC;
00600         break;
00601     }
00602 
00603     if (channel == 1) 
00604     {
00605         base_offset = OFFSET_CH1_BASE;
00606         mezzanine_offset = OFFSET_CH1_MEZ;
00607     }
00608 
00609     /* select the oscillator frequency */
00610     read_byte = edt_reg_read(edt_p, OCM_TX_CONFIG + mezzanine_offset); 
00611     read_byte &= ~CLOCK_SEL_MSK;
00612     read_byte |= clk_select;
00613     edt_reg_write(edt_p, OCM_TX_CONFIG + mezzanine_offset, read_byte );
00614     /* set LIU to correct multiplier */
00615     read_byte = edt_reg_read(edt_p, OCM_CH0_CONFIG0 + base_offset);  
00616     read_byte &= ~RX_SEL_MSK;
00617     read_byte |= clk_val;
00618     edt_reg_write(edt_p, OCM_CH0_CONFIG0 + base_offset , read_byte);  
00619 
00620 
00621     FRETURN("edt_ocm_set_clock_select");
00622 
00623     return 0;
00624 
00625 }
00626 
00642 int
00643 edt_ocm_channel_lock_frontend(EdtDev *edt_p, EdtOCConfig *cfg)
00644 
00645 {
00646     int done = 0;
00647     /* it takes 200 ms every time through */
00648     int t;
00649     int timeout = cfg->timeout;
00650     int timer = 0;
00651     int timed_out = 0;
00652 
00653     uint_t base_offset = 0;
00654     int channel = edt_p->channel_no & 1;
00655 
00656     if (channel == 1)
00657     {
00658         base_offset = OFFSET_CH1_BASE;
00659     }
00660 
00661     /* Reset front end DPLLs */
00662     edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset,  ~(SLK_EN | PLL_EN));
00663 
00664     edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, SYS_EN);
00665 
00666     if (cfg->flags & EDT_OCX_ENABLE_MEM && (edt_p->channel_no == 0))
00667         edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, RAM_EN );
00668     else
00669         edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~RAM_EN );
00670 
00671     if (cfg->flags & EDT_OCX_PRBS_EN)
00672     {
00673         edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, PLL_EN);
00674         return 0;
00675     }
00676 
00677     if (edt_p->channel_no < 2 && !(cfg->flags & EDT_OCX_NO_SIG_DET))
00678     {
00679         if (!edt_ocx_channel_signal_detect(edt_p, timeout))
00680         {
00681             edt_msg(EDT_MSG_WARNING,"\rChannel %d no signal detected -  check signal input", channel);
00682             return -1;
00683         }  
00684 
00685     }
00686     timer = 0;
00687     timed_out = 0;
00688 
00689     while (done == 0 && !timed_out)
00690     {
00691         /* enable SLK */
00692         edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, SLK_EN); 
00693         
00694         /* test if SLK is locked */
00695         /* LOL is a reliable indication of some lock problems but not all */
00696         t = edt_wait_register_bits_low_timer(edt_p, OCM_CH0_STATUS+base_offset, LOL,  cfg->receive_dcm_timeout);
00697         
00698         if (t <  (int) cfg->receive_dcm_timeout)
00699         {
00700             
00701             edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, PLL_EN); 
00702         
00703             t = edt_wait_register_bits_high_timer(edt_p, OCM_CH0_ENABLE + base_offset, RX_LOCK, cfg->receive_dcm_timeout);
00704 
00705             timer = t;
00706 
00707             if (t >=  (int) cfg->receive_dcm_timeout)
00708             {
00709                 edt_msg(EDT_MSG_WARNING,"\rChannel %d FPGA PLL not locked check signal input type", channel);
00710                 /* reset slk and dcm enable */
00711                 edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~(SLK_EN | PLL_EN));
00712                 timed_out = TRUE;
00713             }
00714             else
00715                 done = TRUE;
00716         }
00717         else
00718         {
00719             edt_msg(EDT_MSG_WARNING,"\rChannel %d LIU PLL not locked check signal input type", channel);
00720             /* reset slk and dcm enable */
00721             edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~(SLK_EN | PLL_EN));
00722         }
00723 
00724         if (timeout)
00725             timed_out = timer >= (int) cfg->receive_dcm_timeout;
00726 
00727     }
00728 
00729     if (timed_out)
00730     {
00731         edt_msg(EDT_MSG_FATAL,"\rChannel %d unable to lock PLL -  check signal input", channel);
00732         return -1;
00733     }
00734     else
00735         edt_msg(EDT_MSG_INFO_1,"\rChannel %d PLL locked                    \n", channel);
00736 
00737     return 0;
00738 
00739 }
00740 
00756 int
00757 edt_ocm_check_channel_lock_frontend(EdtDev *edt_p, EdtOCConfig *cfg)
00758 
00759 {
00760     int done = 0;
00761     /* it takes 200 ms every time through */
00762     int t;
00763     int timeout = cfg->timeout;
00764     int timer = 0;
00765     int timed_out = 0;
00766 
00767     uint_t base_offset = 0;
00768     int channel = edt_p->channel_no & 1;
00769 
00770     if (channel == 1)
00771     {
00772         base_offset = OFFSET_CH1_BASE;
00773     }
00774 
00775     /* Reset front end DPLLs */
00776     edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset,  ~(SLK_EN | PLL_EN));
00777 
00778     edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, SYS_EN);
00779 
00780     if (edt_p->channel_no < 2 )
00781     {
00782         if (!edt_ocx_channel_signal_detect(edt_p, timeout))
00783         {
00784             edt_msg(EDT_MSG_WARNING,"\rChannel %d no signal detected -  check signal input", channel);
00785             return 0;
00786         }  
00787 
00788     }
00789 
00790 
00791 
00792     while (done == 0 && !timed_out)
00793     {
00794         /* enable SLK */
00795         edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, SLK_EN); 
00796         
00797         /* test if SLK is locked */
00798         /* LOL is a reliable indication of some lock problems but not all */
00799         t = edt_wait_register_bits_low_timer(edt_p, OCM_CH0_STATUS+base_offset, LOL,  cfg->receive_dcm_timeout);
00800         
00801         printf("SLK_EN time = %d\n", t);
00802        
00803         printf("enable %02x\n", edt_reg_read(edt_p, OCM_CH0_ENABLE + base_offset));  
00804 
00805         if (t <  (int) cfg->receive_dcm_timeout)
00806         {
00807             
00808             edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, PLL_EN); 
00809         
00810             t = edt_wait_register_bits_high_timer(edt_p, OCM_CH0_ENABLE + base_offset, RX_LOCK, cfg->receive_dcm_timeout);
00811 
00812             printf("DCM time = %d\n", t);
00813             timer = t;
00814 
00815             if (t >=  (int) cfg->receive_dcm_timeout)
00816             {
00817                 edt_msg(EDT_MSG_WARNING,"\rChannel %d FPGA PLL not locked check signal input type", channel);
00818                 /* reset slk and dcm enable */
00819                 edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~(SLK_EN | PLL_EN));
00820                 timed_out = TRUE;
00821             }
00822             else
00823                 done = TRUE;
00824         }
00825         else
00826         {
00827             edt_msg(EDT_MSG_WARNING,"\rChannel %d LIU PLL not locked check signal input type", channel);
00828             /* reset slk and dcm enable */
00829             edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~(SLK_EN | PLL_EN));
00830         }
00831 
00832         if (timeout)
00833             timed_out = timer >= (int) cfg->receive_dcm_timeout;
00834 
00835     }
00836 
00837     if (timed_out)
00838     {
00839         edt_msg(EDT_MSG_FATAL,"\rChannel %d unable to lock PLL -  check signal input", channel);
00840         return -1;
00841     }
00842     else
00843         edt_msg(EDT_MSG_INFO_1,"\rChannel %d PLL locked                    \n", channel);
00844 
00845     return 0;
00846 
00847 }
00865 int
00866 edt_ocm_channel_setup(EdtDev *edt_p, EdtOCConfig *cfg)
00867 
00868 
00869 {
00870     int channel = edt_p->channel_no;
00871     int base_offset = 0;
00872     int mezzanine_offset = 0;
00873     u_char rx_ctrl ;
00874     u_char rx_filter ;
00875 
00876     FENTER("edt_ocm_channel_setup");
00877 
00878     if (edt_p->mezz.id == MEZZ_OC192)
00879     {
00880         edt_reg_write(edt_p, OC192_CHAN_SELECT, 0);     
00881     }
00882 
00883 
00884     if (channel == 1)
00885     {
00886         base_offset = OFFSET_CH1_BASE;
00887         mezzanine_offset = OFFSET_CH1_MEZ;
00888 
00889     }
00890 
00891     /* set local loopback if requested */
00892     edt_reg_set_bitmask(edt_p, OCM_CH0_CONFIG0 + base_offset, LOCAL_LOOP, (cfg->flags & EDT_OCX_LOOPBACK));
00893 
00894     /* set remote loopback if requested */
00895     edt_reg_set_bitmask(edt_p, OCM_CH0_CONFIG0 + base_offset, REMOTE_LOOP, (cfg->flags & EDT_OCX_REMOTE_LPBK));
00896 
00897     /* set LIU PRBS7 generator if requested */
00898     edt_reg_set_bitmask(edt_p, OCM_CH0_CONFIG0 + base_offset, PRBS_EN, (cfg->flags & EDT_OCX_PRBS_EN));
00899 
00900 
00901     rx_ctrl = (u_char) edt_reg_read(edt_p, OCM_RX_CTRL + mezzanine_offset);
00902 
00903     if (cfg->flags & EDT_OCX_FRAMED)
00904     {
00905         rx_ctrl |= FRAME_EN;
00906         if ((cfg->flags & EDT_OCX_DESCRAMBLE) == 0)
00907             rx_ctrl |= DISABLE_SCRAM;
00908         else
00909             rx_ctrl &= ~DISABLE_SCRAM;
00910     }
00911     else
00912         rx_ctrl &= ~FRAME_EN;
00913 
00914     if (cfg->flags & EDT_OCX_ENABLE_MEM)
00915         rx_ctrl |= RX_DATA_SRC_2G;
00916     else
00917         rx_ctrl &= ~RX_DATA_SRC_2G;
00918 
00919     edt_reg_write(edt_p, OCM_RX_CTRL + mezzanine_offset, rx_ctrl); 
00920 
00921     rx_filter = (u_char) edt_reg_read(edt_p, OCM_RX_FILTER + mezzanine_offset);
00922     rx_filter &= ~OVERHEAD_ONLY; 
00923     if (cfg->flags & EDT_OCX_OVHD_ONLY) 
00924     {
00925         if (cfg->flags & EDT_OCX_FRAMED)
00926             rx_filter |= OVERHEAD_ONLY; 
00927         else
00928             edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
00929     }
00930     /* enable data substitution */
00931     rx_filter &= ~(EN_DATA_COUNTER | COUNT_FREERUN); 
00932     if (cfg->flags &  EDT_OCX_ENABLE_COUNT_DATA) 
00933         rx_filter |= EN_DATA_COUNTER;
00934     if (cfg->flags & EDT_OCX_FREERUN_COUNT_DATA)
00935         rx_filter |= COUNT_FREERUN;
00936     /* enable all bytes from ethernet 8b/10b decoder */
00937     rx_filter &= ~(EN_ALL_DECODED); 
00938     if (cfg->flags & EDT_OCX_ETHERNET_ALL_DECODE)
00939         rx_filter |= EN_ALL_DECODED;
00940     edt_reg_write(edt_p, OCM_RX_FILTER + mezzanine_offset, rx_filter); 
00941 
00942     FRETURN_I("edt_ocm_channel_setup",0);
00943     return 0;
00944 }
00945 
00957 int
00958 edt_ocm_wait_for_frame(EdtDev *edt_p, int timeout)
00959 
00960 {
00961     u_int cfg;
00962     int mezzanine_offset = 0;
00963     int t = 100;
00964     int rc = 0;
00965 
00966     FENTER("edt_ocm_wait_for_frame");
00967 
00968     if (edt_p->channel_no == 1)
00969     {
00970         mezzanine_offset = OFFSET_CH1_MEZ;
00971     }
00972 
00973     edt_msg(EDTLIB_MSG_INFO_1,"Waiting for frame CH%d", edt_p->channel_no);
00974 
00975     
00976     while (((cfg = edt_reg_read(edt_p, OCM_RX_STATUS + mezzanine_offset)) & FRAMED) == 0 &&
00977         t < timeout)
00978     {
00979         edt_msg(EDTLIB_MSG_INFO_1,".");
00980         cfg = edt_reg_read(edt_p, OCM_RX_CTRL + mezzanine_offset);
00981         edt_reg_write(edt_p, OCM_RX_CTRL + mezzanine_offset, cfg | RESET_FRM);  /* set reset frame */
00982         edt_reg_write(edt_p, OCM_RX_CTRL + mezzanine_offset, cfg);  /* clear it */
00983         edt_msleep(100);
00984         t += 100;
00985     }
00986 
00987     if (t < timeout)
00988         edt_msg(EDTLIB_MSG_INFO_1," framed\n");
00989     else
00990     {
00991         edt_msg(EDTLIB_MSG_FATAL," Framing timed out in %d ms\n", timeout);
00992         rc = -1;
00993     }
00994 
00995     FRETURN_I("edt_ocm_wait_for_frame", rc);
00996 
00997     return rc;
00998 
00999 }
01000 
01001 /***************************************
01002 *
01003 * OC192 board-specific functions
01004 * Most other than the _mdio_ access functions
01005 * have an euqivalent OCM function
01006 *
01007 **************************************/
01008 
01009 /***************************************
01010 *
01011 * OC192 mdio functions to talk to the LIU
01012 *
01013 **************************************/
01014 
01015 
01028 unsigned char 
01029 edt_oc192_mdio_read(EdtDev *edt_p, unsigned char address)
01030 {
01031     unsigned char result=0, byte;
01032     unsigned int val;
01033     int i;
01034 
01035     FENTER_I("edt_oc192_mdio_read",address);
01036     val = 0x60000000;
01037     val |= ((unsigned int) (address & 0x1f))<<18;
01038     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI);
01039     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01040     result = 0;
01041     for (i=31; i>=0; i--) {
01042         if (i>17) {
01043             if (!((val>>i) & 0x1)) {
01044                 edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01045                 edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK | SCLK_TRI);
01046             } else {
01047                 edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01048                 edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01049             }
01050             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01051         } else {
01052             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK_TRI);
01053             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK | SCLK_TRI);
01054             if (i<=8 && i>=1) {
01055                 byte = edt_intfc_read(edt_p, OC192_LIU_MDIO_BUS) & SDATA_IN;
01056                 result |= ((byte>>4)<<(i-1));
01057             }
01058         }
01059     }
01060     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK_TRI);
01061     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK | SCLK_TRI);
01062     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK);
01063     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, 0);
01064 
01065     FRETURN_I("edt_oc192_mdio_read",result);
01066     return result;
01067 }
01068 
01080 void
01081 edt_oc192_mdio_write(EdtDev *edt_p, unsigned char address, unsigned char value)
01082 {
01083     unsigned int val;
01084     int i;
01085 
01086     FENTER_I_I("edt_oc192_mdio_write",address, value);
01087     val = 0x50020000;
01088     val |= ((((unsigned int) (address & 0x1f))<<18) | (unsigned int) value);
01089     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI);
01090     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01091     for (i=31; i>=0; i--) {
01092         if (!((val>>i)&0x1)) {
01093             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01094             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK | SCLK_TRI);
01095         } else {
01096             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01097             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01098         }
01099     }
01100     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01101     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01102     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01103     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01104 
01105     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SCLK) ;
01106     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, 0);
01107     FRETURN("edt_oc192_mdio_write");
01108 }
01109 
01118 void 
01119 edt_oc192_mdio_init(EdtDev *edt_p)
01120 {
01121     int i;
01122 
01123     FENTER("edt_oc192_mdio_init");
01124 
01125     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI);
01126     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01127     for (i=32; i>=0; i--) {
01128         edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01129         edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01130     }
01131     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SCLK);
01132     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, 0);
01133     FRETURN("edt_oc192_mdio_init");
01134 }
01135 
01143 void
01144 edt_oc192_reset_liu(EdtDev *edt_p)
01145 
01146 {
01147     FENTER("edt_oc192_reset_liu");
01148     /* Reset the AMCC S19235 */
01149     edt_intfc_write(edt_p, OC192_ENABLE, edt_intfc_read(edt_p, OC192_ENABLE) | AMCC_RST);
01150     edt_msleep(10);
01151     edt_intfc_write(edt_p, OC192_ENABLE, edt_intfc_read(edt_p, OC192_ENABLE) & ~AMCC_RST);
01152     edt_msleep(10);
01153     edt_oc192_mdio_init(edt_p);
01154     FRETURN("edt_oc192_reset_liu");
01155 }
01156 
01164 void
01165 edt_oc192_mdio_set_clock(EdtDev *edt_p)
01166 
01167 {
01168 
01169 }
01170 
01180 void
01181 edt_oc192_mdio_set_swap(EdtDev *edt_p, int on)
01182 
01183 {
01184     FENTER("edt_oc192_mdio_set_swap");
01185     edt_oc192_mdio_write(edt_p, 0x2, 
01186         (edt_oc192_mdio_read(edt_p, 0x2) & 0xfb) | ((on)? 0x2 : 0) );
01187     FRETURN("edt_oc192_mdio_set_swap");
01188 }
01189 
01197 void
01198 edt_oc192_mdio_dump(EdtDev *edt_p)
01199 
01200 {       
01201     uint_t i;
01202 
01203     for (i=1; i<=0x1f; i++)
01204         if (i<0x11 || i>0x1d)
01205             printf("%02xH       :  %02xH\n", i, edt_oc192_mdio_read(edt_p, (u_char) i));
01206 }
01207 
01208 
01218 void
01219 edt_oc192_mdio_loopback(EdtDev *edt_p, int on)
01220 
01221 {
01222     FENTER("edt_oc192_mdio_loopback");
01223     edt_oc192_mdio_write(edt_p, 0x1, edt_oc192_mdio_read(edt_p, 0x1) & 0xfd | ((on)? 0:0x2) );
01224     FRETURN("edt_oc192_mdio_loopback");
01225 }
01226 
01236 void
01237 edt_oc192_mdio_set_prbs23(EdtDev *edt_p, int on)
01238 {
01239     /*
01240     * Select prbs23 code
01241     */
01242     FENTER("edt_oc192_mdio_set_prbs23");
01243     edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xe7) | (on) ? 0x10 : 0);
01244     FRETURN("edt_oc192_mdio_set_prbs23");
01245 }
01246 
01256 void
01257 edt_oc192_mdio_set_prbs31(EdtDev *edt_p, int on)
01258 {
01259     /*
01260     * Select prbs23 code
01261     */
01262     FENTER("edt_oc192_mdio_set_prbs31");
01263     edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xe7) | (on) ? 0x11 : 0);
01264     FRETURN("edt_oc192_mdio_set_prbs31");
01265 }
01266 
01274 void
01275 edt_oc192_mdio_standard(EdtDev *edt_p)
01276 
01277 {
01278     FENTER("edt_oc192_mdio_standard");
01279     /*
01280     * Refclk is 155.52, turn on DATA_SWAP
01281     */
01282     edt_oc192_mdio_set_swap(edt_p, 1);
01283 
01284     /*
01285     * Bit 2-0
01286     * Phase offset between high speed recovered data and clock for improved BER
01287     * 000 => + 8.5 ps (default)
01288     * 111 => - 11.0 ps
01289     *
01290     * Bit 7-6
01291     * Post amplifier offset adjust
01292     * 
01293     */
01294     /* 
01295     * post amp equalization adjust
01296     * bit 4-2
01297     * 000               No equalization                         -0.8dB
01298     * 001               0% - 5%                                         1.4dB
01299     * 010               5% - 10%                                        2.4dB
01300     * .......
01301     * 111               30% - 35%                                       7.5dB
01302     */
01303     edt_oc192_mdio_write(edt_p, 0xe, (edt_oc192_mdio_read(edt_p, 0xe) & 0xfb) | 0x18 );
01304 
01305     FRETURN("edt_oc192_mdio_standard");
01306 }
01307 
01319 int
01320 edt_oc192_set_liu(EdtDev *edt_p, int mode)
01321 
01322 {
01323     int rc = 0;
01324     FENTER("edt_oc192_set_liu");
01325 
01326     edt_oc192_reset_liu(edt_p);
01327     edt_oc192_mdio_standard(edt_p);
01328 
01329     switch(mode)
01330     {
01331     case EDT_OC192_LIU_NORMAL:
01332         break;
01333 
01334     case EDT_OC192_LIU_LOOPBACK:
01335         edt_oc192_mdio_loopback(edt_p, 1);
01336         break;
01337 
01338     case EDT_OC192_LIU_REMOTE_LPBK:
01339 
01340         edt_oc192_mdio_write(edt_p, 1, 
01341             (edt_oc192_mdio_read(edt_p, 1) & ~3) | 2);
01342         edt_oc192_mdio_write(edt_p,2,
01343             (edt_oc192_mdio_read(edt_p, 2) & ~0x10));
01344         edt_oc192_mdio_write(edt_p, 0x5, 
01345             edt_oc192_mdio_read(edt_p, 0x5) & ~(0x48));
01346 
01347         break;
01348 
01349     case EDT_OC192_LIU_BIST_TX:
01350         /*
01351         * Refclk is 155.52, turn on DATA_SWAP
01352         */
01353         edt_oc192_mdio_set_swap(edt_p, 1);
01354         /*
01355         * Select prbs23 code
01356         */
01357         edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xf7) | 0x10);
01358         /*
01359         * Transmit built in self test mode
01360         */
01361         edt_oc192_mdio_write(edt_p, 0x5, edt_oc192_mdio_read(edt_p, 0x5) | 0x40);
01362         /*
01363         * Turn on diagnostic loopback
01364         */
01365         edt_oc192_mdio_loopback(edt_p, 1);
01366         break;
01367 
01368     case EDT_OC192_LIU_BIST_TX_EXT:
01369         /*
01370         * Refclk is 155.52, turn on DATA_SWAP
01371         */
01372         edt_oc192_mdio_set_swap(edt_p, 1);
01373         /*
01374         * Select prbs23 code
01375         */
01376         edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xf7) | 0x10);
01377         /*
01378         * Transmit built in self test mode
01379         */
01380         edt_oc192_mdio_write(edt_p, 0x5, edt_oc192_mdio_read(edt_p, 0x5) | 0x40);
01381         /*
01382         * Turn off diagnostic loopback
01383         */
01384         edt_oc192_mdio_loopback(edt_p, 0);
01385         break;
01386 
01387     case EDT_OC192_LIU_BIST_RX:
01388         /*
01389         * Refclk is 155.52, turn on DATA_SWAP
01390         */
01391         edt_oc192_mdio_set_swap(edt_p, 1);
01392         /*
01393         * Select prbs23 code
01394         */
01395         edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xf7) | 0x10);
01396         /*
01397         * Receive built in self test mode
01398         * turn on line loopback
01399         */
01400         edt_oc192_mdio_write(edt_p, 0x5, edt_oc192_mdio_read(edt_p, 0x5) | 0x04);
01401         break;
01402 
01403     default:
01404         rc = -1;
01405     }
01406 
01407     FRETURN_I("edt_oc192_set_liu",rc);
01408     return rc;
01409 }
01410 
01411 
01412 
01424 int
01425 edt_oc192_lock_clocks(EdtDev *edt_p, int timeout)
01426 
01427 {
01428 
01429 
01430     if (edt_p->channel_no == 1 && edt_ocx_lock_local_clock(edt_p, timeout))
01431         return -1;
01432 
01433     if (edt_ocx_lock_channel_clock(edt_p, edt_p->channel_no, timeout))
01434         return -1;
01435 
01436     edt_msg(EDTLIB_MSG_INFO_1,"All System clocks locked          \n");
01437 
01438     return 0;
01439 
01440 }
01441 
01442 const char *
01443 edt_ocx_rate_name(EdtLineRate line_rate)
01444 
01445 {
01446     char *rc = "UNKNOWN";
01447 
01448     switch (line_rate) {
01449         case STM1_RATE:
01450             rc = "STM1";
01451             break;
01452 
01453         case STM4_RATE:
01454             rc = "STM4";
01455             break;
01456 
01457         case OC3_RATE:      
01458             rc = "OC3";
01459             break;
01460 
01461         case OC12_RATE:     
01462             rc = "OC12";
01463             break;
01464 
01465         case GIGE_RATE:
01466             rc = "GIGE";
01467             break;
01468 
01469         case STM16_RATE:            
01470             rc = "STM16";
01471             break;
01472 
01473         case OC48_RATE:     
01474             rc = "OC48";
01475             break;
01476 
01477         case OTU1_RATE:
01478             rc = "OTU1";
01479             break;
01480 
01481         case GIG10E_RATE:
01482             rc = "GIG10E";
01483             break;
01484 
01485         case OTU2_RATE:
01486             rc = "OTU2";
01487             break;
01488 
01489         case STM64_RATE:
01490             rc = "STM64";
01491             break;
01492 
01493         case OC192_RATE:
01494             rc =  "OC192";
01495             break;
01496         case OTU2E_RATE:
01497             rc = "OTU2E";
01498             break;
01499         case OTU2F_RATE:
01500             rc = "OTU2E";
01501             break;
01502 
01503         default:
01504             break;
01505     } 
01506     return rc;
01507 }
01508 
01509 int
01510 edt_ocx_is_demuxable(EdtLineRate line_rate)
01511 
01512 {
01513     u_char rc = 0;
01514 
01515     switch (line_rate) {
01516         case STM1_RATE:
01517          case STM4_RATE:
01518          case OC3_RATE:     
01519         case OC12_RATE:     
01520         case STM16_RATE:            
01521         case OC48_RATE:     
01522         case OTU1_RATE:
01523         case OTU2_RATE:
01524         case STM64_RATE:
01525         case OC192_RATE:
01526         case OTU2E_RATE:
01527         case OTU2F_RATE:
01528             return TRUE;
01529 
01530         default:
01531             break;
01532     } 
01533     return rc;
01534 }
01535 
01536 int edt_oc192_check_rate(EdtDev *edt_p, EdtOCConfig *cfg, EdtLineRate rate)
01537 
01538 {
01539     int rc = 0;
01540     double r1 = 0;
01541     double r2 = 0;
01542     double r3 = 0;
01543 
01544     cfg->line_rate = rate;
01545 
01546     if (rc == 0)
01547     {
01548         /* set rate */
01549 
01550         edt_dtime();
01551 
01552         /* disable selected channel */
01553         edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, 0);
01554 
01555         /* reset lsb first which means msb is first in time */
01556         edt_ocx_reset_sys_en(edt_p, edt_p->channel_no);
01557 
01558         /* If new bitfile, resynch SYS_LOCK for this channel */
01559         edt_ocx_lock_channel_clock(edt_p, edt_p->channel_no, cfg->timeout);
01560 
01561         /* select the correct clock source */
01562         edt_oc192_set_clock_select(edt_p, cfg->line_rate);
01563 
01564         r1 = edt_dtime();
01565         /* OK, configure channel parameters */
01566         if (rc == 0)
01567         {
01568             rc = edt_oc192_channel_setup(edt_p, cfg);
01569 
01570             r2 = edt_dtime();
01571 
01572             if (rc == 0)
01573             {
01574                 rc = edt_wait_register_bits_high(edt_p, OC192_LIU_STATUS, 1, 10);
01575 
01576                 r3 = edt_dtime();
01577             }
01578         }
01579     }
01580 
01581     return rc;
01582 
01583 }
01584 
01585 int edt_ocm_check_rate(EdtDev *edt_p, EdtOCConfig *cfg, EdtLineRate rate)
01586 
01587 {
01588     int rc = 0;
01589     double r1 = 0;
01590     double r2 = 0;
01591     double r3 = 0;
01592     int channel = edt_p->channel_no;
01593     int base_offset = 0;
01594     int mezzanine_offset = 0;
01595 
01596     u_int cfg_reg = OCM_CH0_CONFIG0 + (channel)?OFFSET_CH1_BASE:0;
01597     u_int stat_reg =  OCM_CH0_STATUS + (channel)?OFFSET_CH1_BASE:0;
01598     
01599     cfg->line_rate = rate;
01600 
01601     if (rc == 0)
01602     {
01603         /* set rate */
01604 
01605         edt_dtime();
01606 
01607         /* disable selected channel */
01608         edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, 0);
01609 
01610         /* reset lsb first which means msb is first in time */
01611         edt_ocx_reset_sys_en(edt_p, edt_p->channel_no);
01612 
01613         /* If new bitfile, resynch SYS_LOCK for this channel */
01614         edt_ocx_lock_channel_clock(edt_p, edt_p->channel_no, cfg->timeout);
01615 
01616         /* select the correct clock source */
01617         edt_ocm_set_clock_select(edt_p, cfg->line_rate);
01618 
01619         r1 = edt_dtime();
01620         /* OK, configure channel parameters */
01621         if (rc == 0)
01622         {
01623             edt_reg_write(edt_p, cfg_reg, 0xf);
01624 
01625             
01626             rc = edt_ocm_channel_setup(edt_p, cfg);
01627 
01628             r2 = edt_dtime();
01629 
01630             if (rc == 0)
01631             {
01632                 rc = edt_wait_register_bits_high(edt_p, OC192_LIU_STATUS, 1, 10);
01633 
01634                 r3 = edt_dtime();
01635             }
01636         }
01637 
01638     }
01639 
01640     return rc;
01641 
01642 }
01643 
01644 EdtLineRate edt_oc192_get_rate(EdtDev *edt_p, EdtOCConfig *in_cfg)
01645 
01646 {
01647     EdtLineRate rc = UNKNOWN_RATE;
01648     EdtOCConfig cfg;
01649     edt_ocx_cfg_init(&cfg,
01650         0,
01651         500, 
01652         STM64_RATE);
01653 
01654     if (in_cfg)
01655         strncpy(cfg.mezz_0,in_cfg->mezz_0,sizeof(cfg.mezz_0)-1);
01656 
01657     
01658     
01659     edt_ocx_base_init(edt_p, &cfg);
01660     if (edt_p->channel_no & 1)
01661     {
01662         
01663         if (edt_oc192_check_rate(edt_p, &cfg, STM64_RATE) == 0)
01664         rc = STM64_RATE;
01665     else if (edt_oc192_check_rate(edt_p, &cfg, GIG10E_RATE) == 0)
01666         rc = GIG10E_RATE;
01667     else if (edt_oc192_check_rate(edt_p, &cfg, OTU2_RATE) == 0)
01668         rc = OTU2_RATE;
01669     else if (edt_oc192_check_rate(edt_p, &cfg, OTU2E_RATE) == 0)
01670         rc = OTU2E_RATE;
01671 
01672     }
01673     else
01674     {
01675         if (edt_ocm_check_rate(edt_p, &cfg, STM16_RATE) == 0)
01676             rc = STM16_RATE;
01677         else if (edt_ocm_check_rate(edt_p, &cfg, STM4_RATE) == 0)
01678             rc = STM4_RATE;
01679         else if (edt_ocm_check_rate(edt_p, &cfg, STM1_RATE) == 0)
01680             rc = STM1_RATE;
01681         else if (edt_ocm_check_rate(edt_p, &cfg, GIGE_RATE) == 0)
01682             rc = GIGE_RATE;
01683         else if (edt_ocm_check_rate(edt_p, &cfg, OTU1_RATE) == 0)
01684             rc = OTU1_RATE;
01685 
01686     }
01687     
01688     return rc;
01689 }
01690 
01702 int
01703 edt_msdv_lock_clocks(EdtDev *edt_p, int timeout)
01704 
01705 {
01706 
01707 
01708     if (edt_ocx_lock_local_clock(edt_p, timeout) ||
01709         (edt_wait_register_bits_high (edt_p, OCM_CH0_ENABLE, SYS_LOCK,timeout)))
01710     {
01711         edt_msg(EDTLIB_MSG_FATAL,"\rMezzanine System clock not locked");
01712         return -1;
01713 
01714     }
01715 
01716     edt_msg(EDTLIB_MSG_INFO_1,"All System clocks locked          \n");
01717 
01718     return 0;
01719 
01720 }
01721 
01734 char *
01735 edt_oc192_mezz_filename_gs(EdtDev *edt_p, EdtOCConfig * cfg)
01736 
01737 {
01738     char *target_bitfile = NULL;
01739 
01740     switch (cfg->line_rate) {
01741         case OC3_RATE:      
01742         case OC12_RATE:     
01743         case STM1_RATE:
01744         case STM4_RATE:
01745             if (edt_p->mezz.extended_rev > 1)
01746                 target_bitfile="oc12m2.bit";
01747             else
01748                 target_bitfile="oc12m.bit";
01749 
01750 
01751             break;
01752 
01753         case STM16_RATE:            
01754         case OC48_RATE:     
01755             if (edt_p->mezz.extended_rev > 1)
01756                 target_bitfile="oc48m2.bit";
01757             else
01758                 target_bitfile="oc48m.bit";
01759 
01760             break;
01761         case GIGE_RATE:
01762             if (edt_p->mezz.extended_rev > 1)
01763                 target_bitfile="ethernet_1gbe2.bit";
01764             else
01765                 target_bitfile="ethernet_1gbe.bit";
01766             break;
01767 
01768         case OTU2_RATE:
01769         case OTU2E_RATE:
01770             /* Only supported in raw bits mode (no framing, etc). */
01771         case STM64_RATE:
01772         case OC192_RATE:
01773             if (edt_p->mezz.extended_rev > 1)
01774                 target_bitfile="oc192am2.bit";
01775             else
01776                 target_bitfile="oc192am.bit";
01777             break;
01778         case GIG10E_RATE:
01779 
01780             if (cfg->flags & EDT_OCX_FRAMED)
01781             {
01782                 if (edt_p->mezz.extended_rev > 1)
01783                     target_bitfile="ethernet_10gbe2.bit";
01784                 else
01785                     target_bitfile="ethernet_10gbe.bit";
01786 
01787             }
01788             else
01789             {
01790                 if (edt_p->mezz.extended_rev > 1)
01791                     target_bitfile="oc192am2.bit";
01792                 else
01793                     target_bitfile="oc192am.bit";
01794             }
01795             break;
01796 
01797     }
01798 
01799     return target_bitfile;
01800 
01801 }
01802 
01803 char *
01804 edt_oc192_mezz_filename(EdtDev *edt_p, EdtOCConfig * cfg)
01805 
01806 {
01807     char *target_bitfile = NULL;
01808 
01809     if (edt_p->devid == PGS4_ID)
01810         return edt_oc192_mezz_filename_gs(edt_p, cfg);
01811 
01812     switch (cfg->line_rate) {
01813         case OC3_RATE:      
01814         case OC12_RATE:     
01815         case OC48_RATE:     
01816         case STM1_RATE:
01817         case STM4_RATE:
01818         case STM16_RATE:
01819         case OTU1_RATE:
01820 
01821         case OTU2_RATE:
01822         case OTU2E_RATE:
01823             /* Only supported in raw bits mode (no framing, etc). */
01824         case STM64_RATE:
01825         case OC192_RATE:
01826 
01827             if (edt_p->mezz.extended_rev > 1)
01828                 target_bitfile="oc192am2.bit";
01829             else
01830                 target_bitfile="oc192am.bit";
01831 
01832             cfg->dualmode = TRUE;
01833 
01834             break;
01835 
01836 
01837         case GIGE_RATE:
01838             if (cfg->flags & EDT_OCX_FRAMED)
01839             {
01840                 if (edt_p->mezz.extended_rev > 1)
01841                     target_bitfile="ethernet_1gbe2.bit";
01842                 else
01843                     target_bitfile="ethernet_1gbe.bit";
01844                 cfg->dualmode = FALSE;
01845             }
01846             else
01847             {
01848 
01849                 if (edt_p->mezz.extended_rev > 1)
01850                     target_bitfile="oc192am2.bit";
01851                 else
01852                     target_bitfile="oc192am.bit";
01853                 cfg->dualmode = TRUE;
01854             }
01855             break;
01856 
01857         case GIG10E_RATE:
01858 
01859             if (cfg->flags & EDT_OCX_FRAMED)
01860             {
01861                 if (edt_p->mezz.extended_rev > 1)
01862                     target_bitfile="ethernet_10gbe2.bit";
01863                 else
01864                     target_bitfile="ethernet_10gbe.bit";
01865                 cfg->dualmode = FALSE;
01866             }
01867             else
01868             {
01869                 if (edt_p->mezz.extended_rev > 1)
01870                     target_bitfile="oc192am2.bit";
01871                 else
01872                     target_bitfile="oc192am.bit";
01873                 cfg->dualmode = TRUE;
01874             }
01875             break;
01876 
01877     }
01878 
01879     return target_bitfile;
01880 
01881 }
01882 
01883 
01895 char *
01896 edt_net10g_mezz_filename(EdtDev *edt_p, EdtOCConfig *cfg)
01897 
01898 {
01899     char *target_bitfile = NULL;
01900 
01901     target_bitfile = "net10g_v5_sdh.bit";
01902 
01903 
01904 
01905     return target_bitfile;
01906 
01907 }
01908 
01909 
01910 
01927 int
01928 edt_oc192_load_default_mezzanine(EdtDev *edt_p, EdtOCConfig *cfg)
01929 
01930 {
01931     int rc = 0;
01932 
01933     char *bitname = edt_oc192_mezz_filename(edt_p, cfg);
01934 
01935 
01936     if (cfg->mezz_0)
01937         if (cfg->mezz_0[0])
01938             bitname = cfg->mezz_0;
01939 
01940     printf("Loading default %s\n", bitname);
01941 
01942     rc = edt_bitload(edt_p, NULL, bitname, BITLOAD_FLAGS_MEZZANINE, 0);
01943 
01944     if (cfg->dualmode)
01945         edt_reg_or(edt_p, OC192_DUAL_CHANNEL_MODE, 4);
01946 
01947     return rc;
01948 }
01949 
01950 
01963 int
01964 edt_oc192_speed_capable(int channel, EdtLineRate line_rate)
01965 
01966 {
01967     int rc = -1;
01968 
01969     switch (line_rate) {
01970         case STM1_RATE:
01971         case STM4_RATE:
01972         case STM16_RATE:            
01973         case OC3_RATE:      
01974         case OC12_RATE:     
01975         case OC48_RATE:     
01976         case GIGE_RATE:
01977         case OTU1_RATE:
01978             if ((channel & 1) == 0)
01979                 rc = 0;
01980             break;
01981 
01982         case OTU2_RATE:
01983         case OTU2E_RATE:
01984             /* Only supported in raw bits mode (no framing, etc). */
01985         case GIG10E_RATE:
01986         case STM64_RATE:
01987         case OC192_RATE:
01988             if ((channel & 1) == 1)
01989                 rc = 0;
01990             break;
01991 
01992         default:
01993             edt_msg(EDTLIB_MSG_FATAL,"Unknown bit rate %d\n", line_rate);
01994             rc =  -1;
01995 
01996     } 
01997     return rc;
01998 
01999 }
02000 
02001 
02002 
02003 
02004 
02018 int
02019 edt_oc192_has_mezz_bitfile(EdtDev *edt_p, const char *bitfile_name)
02020 
02021 {
02022     int rc;
02023     FENTER_S("edt_oc192_has_correct_bitfile",bitfile_name);
02024 
02025     rc = strcmp(edt_p->bfd.mezz_name0, bitfile_name);
02026 
02027     FRETURN_I("edt_oc192_has_correct_bitfile",rc);
02028 
02029     return rc;
02030 }
02031 
02045 int
02046 edt_net10g_has_mezz_bitfile(EdtDev *edt_p, const char *bitfile_name)
02047 
02048 {
02049     int rc;
02050     FENTER_S("edt_net10g_has_correct_bitfile",bitfile_name);
02051 
02052     rc = strcmp(edt_p->bfd.mezz_name0, bitfile_name);
02053 
02054     FRETURN_I("edt_net10g_has_correct_bitfile",rc);
02055 
02056     return rc;
02057 }
02058 
02073 int
02074 edt_oc192_set_clock_select(EdtDev *edt_p, EdtLineRate line_rate)
02075 
02076 {
02077     int channel = edt_p->channel_no;
02078     int clk_select = 0;
02079 
02080     int rc = 0;
02081 
02082     FENTER_I("edt_oc192_set_clock_select", line_rate);
02083 
02084     if ((channel & 1) == 0) 
02085     {
02086         edt_reg_write(edt_p, OC192_CHAN_SELECT, 0x0);
02087 
02088         return edt_ocm_set_clock_select(edt_p, line_rate);
02089 
02090     }
02091     else
02092     {
02093         edt_reg_write(edt_p, OC192_CHAN_SELECT, 0x1);
02094         /* somehow affecting module not ready */
02095         edt_reg_write(edt_p, OC192_ENABLE, PLL_EN);
02096 
02097         rc = edt_wait_register_bits_high(edt_p, OC192_ENABLE, 0x40, 300);
02098 
02099         /* select clock in register. */
02100         switch (line_rate)
02101         {
02102         case OC192_RATE:
02103         case STM64_RATE:
02104             clk_select = OC192_REFCLK_OC;
02105             break;
02106         case OTU2_RATE:
02107             clk_select = OC192_REFCLK_OTU2;
02108             break;
02109         case OTU2E_RATE:
02110             clk_select = OC192_REFCLK_10GBER_FEC;
02111             break;
02112 
02113         case GIG10E_RATE:
02114             clk_select = OC192_REFCLK_10GBER;
02115             break;
02116 
02117         case GIGE_RATE:
02118         case OC3_RATE:      
02119         case STM1_RATE:
02120         case OC12_RATE:  
02121         case STM4_RATE:
02122         case STM16_RATE:            
02123         case OC48_RATE:
02124         case OTU2F_RATE:
02125         default:
02126             /*Invalid for ch1 oc192*/
02127             clk_select = OC192_REFCLK_OC;
02128             return 1;
02129         }
02130 
02131         edt_reg_write(edt_p, OC192_REF_CLOCK, clk_select);
02132 
02133     }
02134 
02135     FRETURN("edt_oc192_set_clock_select");
02136 
02137     return 0;
02138 
02139 }
02140 
02141 double edt_oc192_get_measured_frequency(EdtDev *edt_p, int clock)
02142 
02143 {
02144     u_char a0;
02145     int reg5051;
02146     double value;
02147 
02148     a0 = edt_reg_read(edt_p, OC192_DUAL_CHANNEL_MODE);
02149 
02150     a0 &= ~OC192_FREQ_MASK;
02151 
02152     a0 |= ((clock) << OC192_FREQ_SHIFT) & OC192_FREQ_MASK;
02153 
02154     edt_reg_write(edt_p, OC192_DUAL_CHANNEL_MODE, a0);
02155 
02156     edt_msleep(10);
02157 
02158     reg5051 = edt_intfc_read(edt_p, 0x51) << 8;
02159     /* deal with wraparound */
02160     if ((clock == OC192_FREQ_RX1 || clock == OC192_FREQ_TX1) && reg5051 == 0)
02161         reg5051 = 0x1000;
02162     reg5051 |= edt_intfc_read(edt_p, 0x50);
02163 
02164 
02165     if (clock == OC192_FREQ_RX1 || clock == OC192_FREQ_TX1)
02166         value = (double) reg5051 * 256 * 0.01;
02167     else
02168         value = (double) reg5051 * 64 * 0.01;
02169 
02170     return value;
02171 
02172 }
02173 
02174 void edt_oc192_set_merged_mezz(EdtDev *edt_p, int state)
02175 
02176 {
02177     if (state)
02178     {
02179         edt_reg_or(edt_p, OC192_DUAL_CHANNEL_MODE, 4);
02180     }
02181     else
02182     {
02183         int val = edt_reg_read(edt_p, OC192_DUAL_CHANNEL_MODE);
02184 
02185         edt_reg_write(edt_p, OC192_DUAL_CHANNEL_MODE, val);
02186     }
02187 }
02188 
02189 
02190 
02201 int
02202 edt_oc192_clear_demux(EdtDev *edt_p)
02203 
02204 {
02205     int i;
02206 
02207     FENTER("edt_oc192_clear_demux");
02208 
02209     /* make sure demux is turned off */
02210     edt_reg_write(edt_p, OC192_DEMUX_BITMASK, 0);
02211     for (i=0x80;i<0x8c;i++)
02212         edt_reg_write(edt_p, OC192_DEMUX_MASK_ADDR, i);
02213 
02214 
02215     FRETURN("edt_oc192_clear_demux");
02216 
02217     return 0;
02218 
02219 }
02220 
02230 void
02231 edt_oc192_set_framer(EdtDev *edt_p, int flags)
02232 
02233 {
02234 
02235     int rx_ctrl;
02236 
02237     FENTER_I("edt_oc192_set_framer", flags);
02238 
02239     rx_ctrl = 0;
02240     if (flags & EDT_OCX_FRAMED)
02241     {
02242         rx_ctrl |= OC192_FRAME_EN;
02243         if ((flags & EDT_OCX_DESCRAMBLE) == 0)
02244             rx_ctrl |= OC192_DISABLE_SCRAM;
02245     }
02246 
02247     edt_reg_write(edt_p, OC192_FRAMING, rx_ctrl);
02248 
02249     FRETURN("edt_oc192_set_framer");
02250 
02251 }
02252 
02271 int
02272 edt_oc192_channel_lock_frontend(EdtDev *edt_p, EdtOCConfig *cfg)
02273 
02274 {
02275     int rc;
02276     int rx_filter;
02277     int liu_check;
02278 
02279     /* AMCC received clock not locked */
02280 
02281     if ((edt_p->channel_no & 1) == 0)
02282         return edt_ocm_channel_lock_frontend(edt_p, cfg);
02283 
02284     if (edt_p->channel_no == 3)
02285         liu_check = 2;
02286     else
02287         liu_check = 1;
02288 
02289     if (cfg->flags & EDT_OCX_PRBS_EN)
02290     {
02291         // no need on loopback prbs
02292     }
02293     else
02294     {
02295         if ((rc = edt_wait_register_bits_high(edt_p, OC192_LIU_STATUS, liu_check, cfg->timeout)))
02296         {
02297             edt_msg(EDTLIB_MSG_FATAL,"AMCC receiver won't lock\n");
02298             return -1;
02299         }
02300         else
02301             edt_msg(EDTLIB_MSG_INFO_1,"AMCC receiver PLL is locked\n");
02302 
02303         /* added 2/13/2008 jsc */
02304 
02305         rx_filter = 0;
02306 
02307         if (cfg->flags & EDT_OCX_OVHD_ONLY) 
02308         {
02309             if (cfg->flags & EDT_OCX_FRAMED)
02310                 rx_filter |= OVERHEAD_ONLY; 
02311             else
02312                 edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
02313         }
02314         if (cfg->flags & EDT_OCX_ODU_KEEP_OVHD)
02315         {
02316             if (cfg->flags & EDT_OCX_FRAMED)
02317                 rx_filter |= ODU_MASKED_PLUS_OVHD;
02318             else
02319                 edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
02320 
02321         }
02322         if (cfg->flags & EDT_OCX_ODU_NO_FEC)
02323         {
02324             if (cfg->flags & EDT_OCX_FRAMED)
02325                 rx_filter |= ODU_NO_FEC;
02326             else
02327                 edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
02328 
02329         }
02330         if (cfg->flags & EDT_OCX_ODU_PASS_THRU)
02331         {
02332             if (cfg->flags & EDT_OCX_FRAMED)
02333                 rx_filter |= ODU_PASS_THRU;
02334             else
02335                 edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
02336 
02337         }
02338         edt_reg_write(edt_p, OC192_RCV_FILTER, rx_filter); 
02339 
02340     }
02341 
02342     edt_reg_write(edt_p, OC192_ENABLE, 0);
02343     edt_reg_write(edt_p, OC192_ENABLE, 0x4);
02344     edt_reg_write(edt_p, OC192_ENABLE, 0xc);
02345     edt_reg_write(edt_p, OC192_ENABLE, 0x1c);
02346     edt_msleep(100);
02347     edt_reg_write(edt_p, OC192_ENABLE, 0x1e);
02348     edt_msleep(50);
02349 
02350     if (edt_p->channel_no == 1)
02351     {
02352         /* Received DCM not locked */
02353         if ((rc = edt_wait_register_bits_high(edt_p, OC192_ENABLE, 0xf0, cfg->receive_dcm_timeout)))
02354         {
02355             edt_msg(EDTLIB_MSG_FATAL,"Receive DCM won't lock\n");
02356             return -1;
02357 
02358         }
02359         else
02360             edt_msg(EDTLIB_MSG_INFO_1,"Receive DCM Locked\n");
02361 
02362     }
02363 
02364 
02365     return 0;
02366 
02367 }
02368 
02387 int
02388 edt_net10g_channel_lock_frontend(EdtDev *edt_p, EdtOCConfig *cfg)
02389 
02390 {
02391     int rc;
02392     int rx_filter;
02393 
02394     /* AMCC received clock not locked */
02395 
02396     if ((rc = edt_wait_register_bits_high(edt_p, OC192_LIU_STATUS, 0x1, cfg->timeout)))
02397     {
02398         edt_msg(EDTLIB_MSG_FATAL,"AMCC receiver won't lock\n");
02399         return -1;
02400     }
02401     else
02402         edt_msg(EDTLIB_MSG_INFO_1,"AMCC receiver PLL is locked\n");
02403 
02404     /* added 2/13/2008 jsc */
02405 
02406     rx_filter = (u_char) edt_reg_read(edt_p, OC192_RCV_FILTER);
02407     rx_filter &= ~OVERHEAD_ONLY; 
02408     if (cfg->flags & EDT_OCX_OVHD_ONLY) 
02409     {
02410         if (cfg->flags & EDT_OCX_FRAMED)
02411             rx_filter |= OVERHEAD_ONLY; 
02412         else
02413             edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
02414     }
02415     edt_reg_write(edt_p, OC192_RCV_FILTER, rx_filter); 
02416 
02417     edt_reg_write(edt_p, OC192_ENABLE, 0);
02418     edt_reg_write(edt_p, OC192_ENABLE, 0x2);
02419     edt_reg_write(edt_p, OC192_ENABLE, 0x6);
02420     edt_reg_write(edt_p, OC192_ENABLE, 0xe);
02421     edt_reg_write(edt_p, OC192_ENABLE, 0x1e);
02422     edt_msleep(100);
02423 
02424     /* Received DCM not locked */
02425     if ((rc = edt_wait_register_bits_high(edt_p, OC192_ENABLE, 0xb0, cfg->timeout)))
02426     {
02427         edt_msg(EDTLIB_MSG_FATAL,"Receive DCM won't lock\n");
02428         return -1;
02429 
02430     }
02431     else
02432         edt_msg(EDTLIB_MSG_INFO_1,"Receive DCM Locked\n");
02433 
02434 
02435 
02436     return 0;
02437 
02438 }
02439 
02440 int
02441 edt_oc192_laser_on(EdtDev *edt_p, EdtOCConfig *cfg)
02442 
02443 {
02444 
02445     EdtXfpSfpRealValue realval;
02446 
02447     if (!cfg->xfp_p)
02448         cfg->xfp_p = edt_open_xfp_sfp_device(edt_p);
02449 
02450     if (!cfg->xfp_p)
02451         return 1;
02452 
02453     edt_xfp_sfp_read_current_values(edt_p, cfg->xfp_p);
02454 
02455     edt_xfp_sfp_real_value(edt_p, cfg->xfp_p, EDT_TX_POWER_MW, &realval);
02456 
02457     return (realval.value > 0);    
02458 }
02459 
02460 int
02461 edt_oc192_enable_laser(EdtDev *edt_p, EdtOCConfig *cfg)
02462 
02463 {
02464 
02465     double t1;
02466     int first = 1;
02467 
02468     edt_reg_write(edt_p, OC192_XCVR_CTL_STAT, 5);
02469 
02470     t1 = edt_timestamp();
02471 
02472     while (!edt_oc192_laser_on(edt_p, cfg))
02473     {
02474 
02475         if (first)
02476         {
02477             edt_msg(EDTLIB_MSG_WARNING,"Waiting for Laser Warmup... This can take up to 30 seconds\n");
02478             first = 0;
02479         }
02480 
02481         edt_msleep(500);
02482 
02483     }
02484 
02485     if (!first)
02486     {
02487         edt_msg(EDTLIB_MSG_WARNING, "Enabled after %f seconds\n", edt_timestamp() - t1);
02488     }
02489 
02490     return 0;
02491 }
02492 
02493 
02510 int
02511 edt_oc192_channel_setup(EdtDev *edt_p, 
02512                         EdtOCConfig *cfg)
02513 
02514 {
02515     int rc;
02516 
02517     edt_reg_write(edt_p, OC192_CHAN_SELECT, 0x1);
02518 
02519     /* turn off output as prbs (must be turned off for tagging) */
02520 
02521     edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0);
02522     /* power up transceiver */
02523 
02524     edt_reg_write(edt_p, OC192_XCVR_CTL_STAT, 0x4);
02525 
02526     if (!(cfg->flags & EDT_OCX_PRBS_EN) && (edt_p->channel_no == 1))
02527     {
02528         if (rc = edt_wait_register_bits_low(edt_p, OC192_XCVR_CTL_STAT, 0x50, cfg->timeout))
02529         {
02530             edt_msg(EDTLIB_MSG_FATAL,"module absent/loss of signal/(module not ready)\n");
02531             return -1;
02532         }
02533     }
02534 
02535     if(cfg->flags & EDT_OCX_LOOPBACK) {
02536         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_LOOPBACK);
02537         edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0x9);
02538     } else if (cfg->flags & EDT_OCX_REMOTE_LPBK)
02539     {
02540         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_REMOTE_LPBK);
02541         edt_oc192_enable_laser(edt_p, cfg);
02542     }
02543     else
02544     {
02545 
02546         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_NORMAL);
02547     }
02548 
02549     /* set framer */
02550 
02551     if (edt_p->channel_no == 1)
02552     {
02553         edt_oc192_set_framer(edt_p, cfg->flags);
02554 
02555         if (cfg->flags & EDT_OCX_TAGGED_DATA)
02556             edt_oc192_set_tagging(edt_p,1,cfg->tagid);
02557     }
02558     else
02559     {
02560         /* turn on memory */
02561         edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0x20);
02562         /* power up transceiver */
02563 
02564         edt_oc192_enable_laser(edt_p, cfg);
02565 
02566     }
02567 
02568     return 0;
02569 }
02570 
02587 int
02588 edt_net10g_channel_setup(EdtDev *edt_p, 
02589                          EdtOCConfig *cfg)
02590 
02591 {
02592     int rc;
02593 
02594     edt_reg_write(edt_p, OC192_CHAN_SELECT, 0x1);
02595 
02596     /* turn off output as prbs (must be turned off for tagging) */
02597 
02598     edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0);
02599     /* power up transceiver */
02600 
02601     edt_reg_write(edt_p, OC192_XCVR_CTL_STAT, 0x4);
02602 
02603     if (rc = edt_wait_register_bits_low(edt_p, OC192_XCVR_CTL_STAT, 0x50, cfg->timeout))
02604     {
02605         edt_msg(EDTLIB_MSG_FATAL,"module absent/loss of signal/(module not ready)\n");
02606         return -1;
02607     }
02608 
02609     if(cfg->flags & EDT_OCX_LOOPBACK) {
02610         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_LOOPBACK);
02611         edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0x19);
02612     } else {
02613         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_NORMAL);
02614     }
02615 
02616     /* set framer */
02617 
02618     edt_oc192_set_framer(edt_p, cfg->flags);
02619 
02620     if (cfg->flags & EDT_OCX_TAGGED_DATA)
02621         edt_oc192_set_tagging(edt_p,1,cfg->tagid);
02622 
02623     return 0;
02624 }
02625 
02638 int
02639 edt_oc192_wait_for_frame(EdtDev *edt_p, int timeout)
02640 
02641 {
02642     int rc = 0;
02643 
02644     FENTER("edt_oc192_wait_for_frame");
02645 
02646     edt_msg(EDTLIB_MSG_INFO_1,"Waiting for frame CH%d", edt_p->channel_no);
02647 
02648     if (rc = edt_wait_register_bits_high(edt_p, OC192_FRAMING, 
02649         OC192_FRAME_LOCK , timeout))
02650     { 
02651         edt_msg(EDTLIB_MSG_FATAL," - Framing timed out\n");
02652         rc = -1;
02653     }
02654     else
02655         edt_msg(EDTLIB_MSG_INFO_1," framed\n");
02656 
02657     FRETURN_I("edt_oc192_wait_for_frame", rc);
02658 
02659     return rc;
02660 
02661 }
02662 
02678 int
02679 edt_oc192_set_tagging(EdtDev *edt_p, int state, int tagid)
02680 
02681 {
02682     u_char mask = 0;
02683 
02684     if (state)
02685     {
02686         /* All boards are set up to acquire only selected 
02687         tag id data, and to transmit on to the 
02688         next board */
02689 
02690         mask = OC192_TAGS_ONLY | OC192_TAGS_XMIT |
02691             (tagid & OC192_TAG_MASK);
02692 
02693         /* Only tag 0 board actually generates tags */
02694 
02695         if (tagid == 0)
02696         {
02697             mask |= OC192_TAG_ON;
02698 
02699         }
02700 
02701         /* turn off output as prbs (must be turned off for tagging) */
02702 
02703         edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0);
02704         /* power up transceiver */
02705 
02706         edt_reg_write(edt_p, OC192_TAG_CTRL, mask);
02707 
02708         edt_reg_write(edt_p, OC192_XCVR_CTL_STAT, 0x5);
02709         /* turn on laser */
02710 
02711 
02712     }
02713     else
02714         edt_reg_write(edt_p, OC192_TAG_CTRL, 0);
02715 
02716     return 0;
02717 
02718 }
02719 
02720 int
02721 edt_oc192_get_overrun(EdtDev *edt_p)
02722 
02723 {
02724     if (edt_p && edt_p->channel_no == 1)
02725     {
02726         u_int i = edt_intfc_read(edt_p, 0x94) & 2;
02727         return (i != 0);
02728     }
02729     else
02730         return FALSE;
02731 }
02732 
02733 int
02734 edt_oc192_get_underrun(EdtDev *edt_p)
02735 
02736 {
02737     if (edt_p && edt_p->channel_no & 1)
02738     {
02739         u_int i = edt_intfc_read(edt_p, 0x94) & 8;
02740         return (i != 0);
02741     }
02742     else
02743         return FALSE;
02744 }
02745 
02746 /******************************************************
02747 *
02748 * edt_ocx_functions - apply to euther OCM or OC 192 mezzanine boards
02749 *
02750 ******************************************************/
02751 
02752 
02753 /***************************************
02754 *
02755 ***************************************/
02756 
02766 char *
02767 edt_ocx_default_bitfile(int mezz_id)
02768 
02769 {
02770     char *workfile = NULL;
02771 
02772     switch (mezz_id)
02773     {
02774     case MEZZ_OCM:
02775         workfile = "ocm";
02776         break;
02777     case MEZZ_OC192:
02778         workfile = "oc192";
02779         break;
02780     case MEZZ_MSDV:
02781         workfile = "msdv";
02782         break;
02783     case MEZZ_NET10G:
02784         workfile = "net10g";
02785         break;
02786 
02787     }
02788 
02789     return workfile;
02790 
02791 }
02792 
02808 int
02809 edt_ocx_check_interface(EdtDev *edt_p, char *target_file, int force_load)
02810 
02811 {
02812     int rc = 0;
02813     char *workfile = target_file;
02814     char *end;
02815 
02816     FENTER_S("edt_ocx_check_interface",target_file);
02817 
02818     edt_get_bitname(edt_p, edt_p->bfd.bitfile_name, sizeof(edt_p->bfd.bitfile_name));
02819 
02820     if (end = strstr(edt_p->bfd.bitfile_name, ".bit"))
02821             *end = 0;
02822 
02823     if (workfile == NULL || (workfile && (strlen(workfile) == 0)))
02824     {
02825         workfile = edt_ocx_default_bitfile(edt_p->mezz.id);
02826 
02827         if (workfile == NULL)
02828         {
02829             edt_msg(EDTLIB_MSG_FATAL, "Unable to select interface bitfile for mezzanine %x\n",
02830                 edt_p->mezz.id);
02831             return -1;
02832         }
02833     }
02834 
02835     if (strcmp(edt_p->bfd.bitfile_name, workfile))
02836     {
02837 
02838         if (force_load)
02839         {
02840             edt_msg(EDTLIB_MSG_WARNING, "Loading interface file %s\n",
02841                 workfile);
02842 
02843             rc = (edt_bitload(edt_p, NULL, workfile, 0,0) != 0);        
02844 
02845             /* have to get the board description again */
02846             if (rc == 0)
02847                 edt_get_board_description(edt_p, FALSE);
02848 
02849         }
02850         if (rc != 0)
02851         {
02852             edt_msg(EDTLIB_MSG_FATAL, "Unable to load bitfile %s\n", workfile);
02853         }
02854     }
02855 
02856     /* ok */
02857     FRETURN_I("edt_ocx_check_interface",rc);
02858 
02859     return rc;
02860 
02861 }
02862 
02863 
02864 
02865 
02878 int
02879 edt_ocx_lock_clocks(EdtDev *edt_p, int timeout)
02880 
02881 {
02882     switch(edt_p->mezz.id)
02883     {
02884     case MEZZ_OCM:
02885         return edt_ocm_lock_clocks(edt_p, timeout);
02886     case MEZZ_NET10G:
02887     case MEZZ_OC192:
02888         return edt_oc192_lock_clocks(edt_p, timeout);
02889     case MEZZ_MSDV:
02890         return edt_msdv_lock_clocks(edt_p, timeout);
02891     default:
02892         edt_msg(EDTLIB_MSG_FATAL, "Mezz ID must be OCM or OC192 in edt_ocx_lock_clocks\n");
02893         return -1;
02894     }
02895 
02896 }
02897 
02898 
02899 
02919 int
02920 edt_ocx_load_default_mezzanine(EdtDev *edt_p, EdtOCConfig *cfg)
02921 
02922 {
02923     switch(edt_p->mezz.id)
02924     {
02925     case MEZZ_OCM:
02926         return edt_ocm_load_default_mezzanine(edt_p, cfg);
02927     case MEZZ_OC192:
02928         return edt_oc192_load_default_mezzanine(edt_p, cfg);
02929     case MEZZ_MSDV:
02930         return edt_msdv_load_default_mezzanine(edt_p, cfg);
02931     case MEZZ_NET10G:
02932         return edt_net10g_load_default_mezzanine(edt_p, cfg);
02933     default:
02934         edt_msg(EDTLIB_MSG_FATAL, "Mezz ID must be OCM, OC192, MSDV, or NET10G in edt_ocx_load_fault_mezzanine\n");
02935         return -1;
02936     }
02937 }
02938 
02939 
02956 int
02957 edt_ocx_base_init(EdtDev *edt_p, 
02958                   EdtOCConfig *cfg)
02959 
02960 {
02961     int rc = 0;
02962     int force_load = !(cfg->flags & EDT_OCX_SKIP_LOAD);
02963 
02964 
02965     FENTER("edt_ocx_init");
02966 
02967 
02968     /* identify mezz board */
02969     if ((rc = edt_get_board_description(edt_p, force_load)) != 0)
02970     {
02971         edt_msg(EDTLIB_MSG_FATAL, "Unable to get board description\n");
02972         return rc;
02973     }
02974 
02975     if (edt_p->mezz.id != MEZZ_OCM && edt_p->mezz.id != MEZZ_OC192 && edt_p->mezz.id != MEZZ_MSDV &&
02976         edt_p->mezz.id != MEZZ_NET10G)
02977     {
02978 
02979         edt_msg(EDTLIB_MSG_FATAL, "Mezzanine ID = %d, OCM or OC192 or MSDV expected\n",
02980             edt_p->mezz.id);
02981 
02982         edt_print_board_description(edt_p); 
02983 
02984         return -1;
02985     }
02986 
02987 
02988     /* load base bitfile if necessary */
02989     /* check bitfile */
02990 
02991     if ((rc = edt_ocx_check_interface(edt_p, cfg->intfc, !(cfg->flags & EDT_OCX_SKIP_LOAD))) != 0)
02992     {
02993         FRETURN_I("edt_ocx_check_bitfiles",rc);
02994         return rc;
02995     }
02996 
02997     /* load default mezzanine if necessary */
02998     if (edt_p->bfd.mezz_name0[0] == 0)
02999     {
03000         edt_ocx_load_default_mezzanine(edt_p, cfg);
03001 
03002     }
03003 
03004     /* Reset channel enables and 100 MHz ref. clock */
03005     edt_msg(EDTLIB_MSG_INFO_1,"Full init\n");
03006 
03007     edt_set_autodir(edt_p, 0);
03008 
03009     edt_reg_write(edt_p, PCD_CMD, 0); /* reset user xilinx */
03010     edt_reg_write(edt_p, PCD_CMD, 0); /* reset user xilinx */
03011     edt_reg_write(edt_p, PCD_CMD, 8);
03012     edt_reg_write(edt_p, SSD16_CHENL, 0); /* disable all channels */
03013     edt_reg_write(edt_p, SSD16_LSBL, 0); /* reset lsb first which means msb is first in time */
03014 
03015     /* reset sysclk on both mezzanine xilinx */
03016     /* note some redundancy for OC192, since only one channel is active at a time */
03017 
03018     edt_reg_write(edt_p, OCM_CH0_ENABLE , 0x0); /* reset all the OCM enables */
03019     edt_reg_write(edt_p, OCM_CH0_ENABLE , RAM_EN | SYS_EN); /* reset all the OCM enables */
03020     edt_reg_write(edt_p, OCM_CH0_ENABLE + OFFSET_CH1_BASE, 0x0); /* reset all the OCM enables */
03021     edt_reg_write(edt_p, OCM_CH0_ENABLE + OFFSET_CH1_BASE, RAM_EN | SYS_EN); /* reset all the OCM enables  RAM_EN not currently used*/
03022     edt_flush_fifo(edt_p) ;         /* Flush the input fifo */
03023 
03024     if (cfg->flags & EDT_OCX_SWAP)
03025         edt_reg_write(edt_p, PCD_CONFIG, PCD_BYTESWAP | PCD_SHORTSWAP); 
03026     else
03027         edt_reg_write(edt_p, PCD_CONFIG, 0); 
03028 
03029     /* synch clocks */
03030 
03031     /* get plls working */
03032     rc = edt_ocx_lock_clocks(edt_p, cfg->timeout);
03033 
03034     if (ID_IS_LX(edt_p->devid) && edt_p->mezz.id == MEZZ_OC192 || 
03035         edt_p->mezz.id == MEZZ_NET10G || edt_p->mezz.id == MEZZ_THREEP)
03036     {
03037         if (cfg->line_rate > 48)
03038                 edt_reg_write(edt_p, EDT_PCIE_CFG, 0x54);
03039         else
03040                 edt_reg_write(edt_p, EDT_PCIE_CFG, 0);
03041         
03042     }
03043     else if (ID_IS_LX(edt_p->devid) && edt_p->mezz.id == MEZZ_OCM)
03044     {
03045         edt_reg_write(edt_p, EDT_PCIE_CFG, 0x0);
03046     }
03047 
03048     FRETURN("edt_ocx_base_init");
03049 
03050     return rc;
03051 
03052 }
03053 
03054 
03055 
03068 int
03069 edt_ocx_speed_capable(EdtDev *edt_p, EdtLineRate line_rate)
03070 
03071 {
03072     int rc;
03073 
03074     FENTER("edt_ocx_speed_capable");
03075 
03076     if (edt_p->mezz.id == MEZZ_OC192 || edt_p->mezz.id == MEZZ_NET10G)
03077 
03078         rc = edt_oc192_speed_capable(edt_p->channel_no, line_rate);
03079 
03080     else if (edt_p->mezz.id == MEZZ_OCM)
03081 
03082         rc = edt_ocm_speed_capable(edt_p->channel_no, line_rate);
03083 
03084     else 
03085         rc = -1;
03086 
03087     FRETURN_I("edt_ocx_speed_capable",rc);
03088 
03089     return rc;
03090 
03091 }
03092 
03093 
03094 
03107 int
03108 edt_ocx_has_mezz_bitfile(EdtDev *edt_p, const char *bitfile_name)
03109 
03110 {
03111     int rc = -1;
03112 
03113     FENTER_S("edt_ocx_has_correct_bitfile",bitfile_name);
03114 
03115     if (edt_p->mezz.id == MEZZ_OC192)
03116     {
03117         rc = edt_oc192_has_mezz_bitfile(edt_p, bitfile_name);
03118     }
03119     else if (edt_p->mezz.id == MEZZ_OCM)
03120     {
03121         rc = edt_ocm_has_mezz_bitfile(edt_p, bitfile_name);
03122     }
03123     else if (edt_p->mezz.id == MEZZ_NET10G)
03124     {
03125         rc = edt_net10g_has_mezz_bitfile(edt_p, bitfile_name);
03126     }
03127     else
03128         rc = -1;
03129 
03130 
03131     FRETURN_I("edt_ocx_has_correct_bitfile",rc);
03132 
03133     return rc;
03134 
03135 }
03136 
03137 
03148 const char *
03149 edt_ocx_mezz_filename(EdtDev *edt_p, EdtOCConfig *cfg)
03150 
03151 {
03152     switch(edt_p->mezz.id)
03153     {
03154     case MEZZ_OCM:
03155         return edt_ocm_mezz_filename(edt_p, cfg);
03156     case MEZZ_OC192:
03157         return edt_oc192_mezz_filename(edt_p, cfg);
03158     case MEZZ_NET10G:
03159         return edt_net10g_mezz_filename(edt_p, cfg);
03160     }
03161 
03162     return NULL;
03163 
03164 }
03165 
03179 int
03180 edt_ocx_check_mezz_bitfile(EdtDev *edt_p,
03181                            EdtOCConfig *cfg)
03182 
03183 {  
03184     int channel = edt_p->channel_no & 1;
03185     const char *target_bitfile = NULL;
03186     int rc = 0;
03187     int force_load = (cfg->flags & EDT_OCX_SKIP_LOAD) == 0;
03188 
03189     FENTER("edt_ocx_check_mezz_bitfile");
03190 
03191     if (edt_p->mezz.id == MEZZ_OC192 && cfg->mezz_0[0])
03192         target_bitfile = cfg->mezz_0;
03193     else if (channel == 0 && cfg->mezz_0[0])
03194         target_bitfile = cfg->mezz_0;
03195     else if (cfg->mezz_1[0])
03196         target_bitfile = cfg->mezz_1;
03197 
03198 
03199     if (target_bitfile == NULL)
03200         target_bitfile = edt_ocx_mezz_filename(edt_p,  cfg);
03201 
03202     if (target_bitfile == NULL)
03203     {
03204         edt_msg(EDTLIB_MSG_FATAL,"Invalid bit rate %d\n", cfg->line_rate);
03205         return -1;
03206     }
03207 
03208     if (edt_ocx_has_mezz_bitfile(edt_p, target_bitfile))
03209     {
03210         if (!force_load)
03211         {
03212             edt_msg(EDTLIB_MSG_FATAL,
03213                 "Wrong mezzanine bitfile %s for bit rate %d. \nUnset flag EDT_OCX_SKIP_LOAD to load\n",
03214                 target_bitfile, cfg->line_rate);
03215             return -1;
03216         }
03217 
03218         edt_msg(EDTLIB_MSG_WARNING,"wrong mezzanine bitfile for line_rate - reloading with %s \n",
03219             target_bitfile);
03220 
03221         if (edt_p->mezz.id == MEZZ_OCM)
03222         {
03223             int flags = BITLOAD_FLAGS_OVR | BITLOAD_FLAGS_OCM;
03224             if (channel == 1)
03225                 flags |= BITLOAD_FLAGS_CH1;
03226 
03227             rc = edt_bitload(edt_p, NULL, target_bitfile, flags, 0);
03228         }
03229         else
03230         {
03231             edt_msg(EDTLIB_MSG_INFO_1,"Going to edt_bitload with %s\n", target_bitfile);
03232             rc = edt_bitload(edt_p, NULL, target_bitfile, BITLOAD_FLAGS_MEZZANINE, 0);
03233             if (edt_p->mezz.id == MEZZ_OC192)
03234                 if (cfg->dualmode)
03235                     edt_reg_or(edt_p, OC192_DUAL_CHANNEL_MODE, 4);
03236 
03237         }
03238 
03239     }
03240 
03241     FRETURN_I("edt_ocx_check_mezz_bitfile", rc);
03242 
03243     return rc;
03244 }
03245 
03246 
03247 
03259 int
03260 edt_ocx_set_clock_select(EdtDev *edt_p, EdtLineRate line_rate)
03261 
03262 {
03263     switch(edt_p->mezz.id)
03264     {
03265     case MEZZ_OCM:
03266         return edt_ocm_set_clock_select(edt_p, line_rate);
03267     case MEZZ_OC192:
03268         return edt_oc192_set_clock_select(edt_p, line_rate);
03269 
03270     }
03271 
03272     return -1;
03273 }
03274 
03289 void
03290 edt_ocx_set_channel_enable(EdtDev *edt_p, int channel, int state)
03291 
03292 {
03293     int channel_mask = (1 << channel);
03294     edt_reg_set_bitmask(edt_p, SSD16_CHEN, channel_mask, state);
03295 
03296 }
03297 
03298 void
03299 edt_ocx_set_channel_direction(EdtDev *edt_p, int channel, int do_write)
03300 
03301 {
03302     int channel_mask = (((do_write)?1:0) << channel);
03303     edt_reg_set_bitmask(edt_p, SSD16_CHDIR, channel_mask, do_write);
03304 
03305 }
03306 
03307 
03308 
03323 void
03324 edt_ocx_set_lsbfirst(EdtDev *edt_p, int channel, int state)
03325 
03326 {
03327     int channel_mask = (1 << channel);
03328     if (state)
03329         edt_reg_or(edt_p, SSD16_LSB, channel_mask);
03330     else
03331         edt_reg_and(edt_p, SSD16_LSB, ~channel_mask);
03332 
03333 }
03334 
03348 int
03349 edt_ocx_channel_signal_detect(EdtDev *edt_p, int timeout)
03350 
03351 {
03352     u_int reg = OCM_CH0_STATUS;
03353     u_int bit = SIG_DET;
03354 
03355     switch (edt_p->mezz.id)
03356     {
03357     case MEZZ_OC192:
03358         if (edt_p->channel_no == 1)
03359         {
03360             reg = OC192_XCVR_CTL_STAT;
03361             bit = LOS;
03362         }
03363         else
03364         {
03365             reg = OCM_CH0_STATUS;
03366             bit = SIG_DET;
03367         }
03368         break;
03369     case  MEZZ_OCM:
03370         if (edt_p->channel_no == 1)
03371         {
03372             reg += OFFSET_CH1_BASE;
03373         }
03374         break;
03375     }
03376 
03377     return ! edt_wait_register_bits_high(edt_p, reg, bit, timeout);
03378 }
03379 
03380 
03393 void
03394 edt_ocx_reset_sys_en(EdtDev *edt_p, int channel)
03395 
03396 {
03397     int oc_channel = channel & 1;
03398     int chen = OCM_CH0_ENABLE + (oc_channel)?OFFSET_CH1_BASE:0;
03399 
03400     edt_reg_write(edt_p, chen, 0x0); /* reset the OCM enables */
03401     edt_reg_write(edt_p, chen, SYS_EN); /* reset the OCM enables */
03402 
03403 }
03404 
03419 int
03420 edt_ocx_channel_set_rate(EdtDev *edt_p, EdtOCConfig *cfg)
03421 
03422 
03423 {
03424     int channel = edt_p->channel_no & 1;
03425     int rc = 0;
03426 
03427     FENTER("edt_ocx_channel_set_rate");
03428 
03429     /* make sure board is identified */
03430     if (edt_p->mezz.id == 0xff)
03431     {
03432         if (edt_get_board_description(edt_p, FALSE) != 0)
03433         {
03434             edt_msg(EDTLIB_MSG_FATAL, "Unable to get board description in edt_ocx_channel_set_rate\n");
03435             return -1;
03436         }
03437 
03438     }
03439 
03440     /* check rate */
03441     if (edt_ocx_speed_capable(edt_p, cfg->line_rate))
03442     {
03443         edt_msg(EDTLIB_MSG_FATAL,"This channel %d not capable of this rate %d\n",
03444             channel, cfg->line_rate);
03445         return -1;
03446     }
03447 
03448     /* check bitfile */
03449 
03450     if ((rc = edt_ocx_check_mezz_bitfile(edt_p, cfg)) != 0)
03451     {
03452         edt_msg(EDTLIB_MSG_FATAL,"Can't load desired bitfile\n");
03453         return -1;
03454 
03455     }
03456 
03457     /* load new mezz bitfile if necessary */
03458 
03459     edt_msg(EDTLIB_MSG_INFO_1,"Setting channel %d to rate %d\n", edt_p->channel_no, cfg->line_rate);
03460 
03461     /* disable selected channel */
03462     edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, 0);
03463 
03464     /* reset lsb first which means msb is first in time */
03465 
03466     edt_ocx_set_lsbfirst(edt_p, edt_p->channel_no, cfg->flags & EDT_OCX_LSB_FIRST);
03467 
03468     edt_flush_channel(edt_p, edt_p->channel_no);
03469 
03470     edt_ocx_reset_sys_en(edt_p, edt_p->channel_no);
03471 
03472     /* If new bitfile, resynch SYS_LOCK for this channel */
03473     edt_ocx_lock_channel_clock(edt_p, channel, cfg->timeout);
03474 
03475     /* select the correct clock source */
03476 
03477     edt_ocx_set_clock_select(edt_p, cfg->line_rate);
03478 
03479     edt_ocx_enable_framing_errors(edt_p, FALSE);
03480     edt_ocx_enable_framing_errors(edt_p, TRUE);
03481 
03482     FRETURN("edt_ocx_channel_set_rate");
03483 
03484     return rc;
03485 }
03486 
03498 int
03499 edt_ocx_channel_lock_frontend(EdtDev *edt_p,
03500                               EdtOCConfig *cfg)
03501 
03502 
03503 {
03504     if (edt_p->mezz.id == 0xff)
03505     {
03506         if (edt_get_board_description(edt_p, FALSE) != 0)
03507         {
03508             edt_msg(EDTLIB_MSG_FATAL, "Unable to get board description in edt_ocx_channel_lock_frontend\n");
03509             return -1;
03510         }
03511 
03512     }
03513 
03514     if (edt_p->channel_no & 1)
03515     {
03516         if (edt_p->mezz.id == MEZZ_NET10G)
03517             return edt_net10g_channel_lock_frontend(edt_p, cfg);
03518         else if (edt_p->mezz.id == MEZZ_OC192)
03519             return edt_oc192_channel_lock_frontend(edt_p, cfg);
03520     }
03521 
03522     return edt_ocm_channel_lock_frontend(edt_p, cfg);
03523 
03524 }
03525 
03526 
03538 int
03539 edt_ocx_channel_setup(EdtDev *edt_p,
03540                       EdtOCConfig *cfg)
03541 
03542 
03543 {
03544     /* make sure board is identified */
03545     if (edt_p->mezz.id == 0xff)
03546     {
03547         if (edt_get_board_description(edt_p, FALSE) != 0)
03548         {
03549             edt_msg(EDTLIB_MSG_FATAL, "Unable to get board description in edt_ocx_channel_setup\n");
03550             return -1;
03551         }
03552 
03553     }
03554     if (edt_p->channel_no & 1)
03555         if (edt_p->mezz.id == MEZZ_OC192 || edt_p->mezz.id == MEZZ_NET10G)
03556             return edt_oc192_channel_setup(edt_p, cfg);
03557 
03558     return edt_ocm_channel_setup(edt_p, cfg);
03559 
03560 }
03561 
03584 int
03585 edt_ocx_configure(EdtDev *edt_p, 
03586                   EdtOCConfig *cfg)
03587 
03588 {       
03589     int rc = 0;
03590     /*
03591     * configure the OCM board - assume ocmload has been run
03592     */
03593     /* check correct version of bitfiles loaded */
03594 
03595     FENTER("edt_ocx_configure");
03596 
03597     edt_msg(EDTLIB_MSG_INFO_1,"configure for speed %d on channel %d\n", 
03598         cfg->line_rate, edt_p->channel_no);
03599 
03600     /* load baseboard if requested */
03601 
03602     if (cfg->flags & EDT_OCX_FULL_INIT)
03603     {
03604         if (edt_ocx_base_init(edt_p, cfg) != 0)
03605         {
03606             edt_msg(EDTLIB_MSG_FATAL, "Unable to execute base init for unit %d at rate %d\n",
03607                 edt_p->unit_no, cfg->line_rate);
03608             rc = -1;
03609         }
03610     }
03611     else
03612     {
03613         edt_get_board_description(edt_p, FALSE);
03614     }
03615 
03616     if (rc == 0)
03617     {
03618         /* set rate */
03619 
03620         if (edt_ocx_channel_set_rate(edt_p, cfg) != 0)
03621         {
03622             edt_msg(EDTLIB_MSG_FATAL, "Unable to set rate for unit %d channel %d at rate %d\n",
03623                 edt_p->unit_no, edt_p->channel_no, cfg->line_rate);
03624             rc = -1;
03625         }
03626         /* OK, configure channel parameters */
03627         else if (edt_ocx_channel_setup(edt_p, cfg) != 0)
03628         {
03629             edt_msg(EDTLIB_MSG_FATAL, "Unable to set channel parameters unit %d channel %d at rate %d\n",
03630                 edt_p->unit_no, edt_p->channel_no, cfg->line_rate);
03631             rc = -1;
03632 
03633         }
03634         else if (edt_ocx_channel_lock_frontend(edt_p, cfg) != 0)
03635         {
03636             edt_msg(EDTLIB_MSG_FATAL, "Unable to lock front end unit %d channel %d at rate %d\n",
03637                 edt_p->unit_no, edt_p->channel_no, cfg->line_rate);
03638             rc = -1;
03639 
03640         }
03641     }
03642 
03643     FENTER_I("edt_ocx_configure", rc);
03644 
03645     return rc;
03646 
03647 }
03648 
03649 
03662 int
03663 edt_ocx_wait_for_frame(EdtDev *edt_p, int timeout)
03664 
03665 {
03666 
03667     if (edt_p->mezz.id == MEZZ_OC192 &&
03668         edt_p->channel_no & 1)
03669     {
03670         return edt_oc192_wait_for_frame(edt_p, timeout);
03671     } 
03672     else
03673     {
03674         return edt_ocm_wait_for_frame(edt_p, timeout);
03675     }
03676 }
03677 
03678 int
03679 edt_ocx_prepare_for_dma(EdtDev *edt_p, EdtOCConfig *cfg)
03680 
03681 {
03682 
03683     //edt_reg_write(edt_p, PCD_CMD, 0);
03684     printf("PCD_CMD = %x\n", edt_reg_read(edt_p, PCD_CMD));
03685 
03686     edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, FALSE);
03687 
03688 
03689     //   if (cfg->writing)
03690     //   {
03691     //       edt_reg_write(edt_p, PCD_CMD, 8);
03692     //       edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, TRUE);
03693     //   }
03694 
03695     return 0;
03696 }
03697 
03698 int
03699 edt_ocx_post_start(EdtDev *edt_p, EdtOCConfig *cfg)
03700 
03701 {
03702 
03703     int rc = 0;
03704 
03705     edt_reg_write(edt_p, PCD_CMD, 8);
03706     edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, TRUE);
03707 
03708     /* wait for framed if collecting framed data */
03709     if ((cfg->flags & EDT_OCX_FRAMED) && edt_p->channel_no < 2)
03710     {
03711         rc = edt_ocx_wait_for_frame(edt_p, cfg->frame_timeout);
03712     }
03713 
03714     return rc;
03715 }
03716 
03717 int
03718 edt_ocx_channel_start_cfg(EdtDev *edt_p, EdtOCConfig *cfg, int n)
03719 
03720 {
03721     int rc = 0;
03722 
03723     FENTER("edt_ocx_channel_start_cfg");
03724 
03725     edt_ocx_prepare_for_dma(edt_p, cfg);
03726 
03727     edt_start_buffers(edt_p, n);
03728 
03729     rc = edt_ocx_post_start(edt_p, cfg);
03730 
03731 
03732     FRETURN("edt_ocx_channel_start_cfg");
03733 
03734     return 0;
03735 }
03736 
03737 int
03738 edt_ocx_adjust_phase(EdtDev *edt_p, int value)
03739 
03740 {
03741     int rc = 0;
03742 
03743     return rc;
03744 }
03745 
03746 
03758 int
03759 edt_ocx_channel_start(EdtDev *edt_p)
03760 
03761 {
03762 
03763     FENTER("edt_ocx_start");
03764 
03765     edt_msg(EDTLIB_MSG_INFO_1,"Start buffers\n");
03766 
03767     edt_start_buffers(edt_p, edt_p->ring_buffer_numbufs-1) ; /* start the transfers with all the allocated buffers */
03768 
03769     /* enable selected channel */
03770     edt_reg_write(edt_p, PCD_CMD, 8);
03771 
03772     edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, TRUE);
03773 
03774     edt_msg(EDTLIB_MSG_INFO_1,"enabled\n");
03775 
03776 
03777     FRETURN("edt_ocx_start");
03778 
03779     return 0;
03780 }
03781 
03782 /* Convenience routines because 16 bit accesses seem
03783 to fail sometimes */
03784 
03785 static void
03786 edt_oc192_demux_set_mask_reg(EdtDev *edt_p, u_int reg, u_int column)
03787 
03788 {
03789     edt_reg_write(edt_p,OC192_DEMUX_BITMASK_LO, reg & 0xff);
03790     edt_reg_write(edt_p,OC192_DEMUX_BITMASK_HI, (reg >> 8) & 0xff);
03791     edt_reg_write(edt_p,OC192_DEMUX_MASK_ADDR, (0x80 + ( column >> 4 )));
03792 
03793 }
03794 
03795 static u_int
03796 edt_oc192_demux_get_mask_reg(EdtDev *edt_p, u_int column)
03797 
03798 {
03799     u_int reg;
03800 
03801     edt_reg_write(edt_p, OC192_DEMUX_MASK_ADDR, column >> 4);
03802 
03803     reg = edt_reg_read(edt_p,OC192_DEMUX_BITMASK_RD_LO);
03804     reg |= edt_reg_read(edt_p,OC192_DEMUX_BITMASK_RD_HI) << 8;
03805 
03806     return reg;
03807 
03808 }
03809 
03810 
03811 int
03812 edt_ocx_demux_nbits(EdtLineRate line_rate)
03813 
03814 {
03815     int n = 0;
03816 
03817     switch(line_rate)
03818     {
03819 
03820         case STM64_RATE:
03821         case OC192_RATE:
03822             n = 192;
03823             break;
03824 
03825         case OTU2_RATE:
03826         case OTU2E_RATE:
03827         case OTU2F_RATE:
03828             n = 16;
03829         break;
03830     
03831         case STM1_RATE:
03832         case OC3_RATE:
03833             n = 3;
03834 
03835             break;
03836         case STM4_RATE:
03837         case OC12_RATE:
03838             n = 12;
03839             break;
03840         case STM16_RATE:
03841         case OC48_RATE:
03842             n = 48;
03843             break;
03844     }
03845         
03846 
03847     if (n == 0)
03848         edt_msg(EDTLIB_MSG_FATAL,"Incorrect line rate %d for OC192/OCM\n", line_rate);
03849     return n;
03850 }
03851 
03868 int
03869 edt_oc192_demux_set(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
03870 
03871 {
03872     int n;
03873     int byte = 0;
03874     unsigned int reg;
03875 
03876     reg = 0;
03877     n = edt_ocx_demux_nbits(line_rate);
03878 
03879     if (n == -1)
03880         return -1;
03881 
03882     for (byte=0;byte < n; byte++)
03883     {
03884 
03885         reg = (reg << 1);
03886         reg += (onoff[byte])?0:1;
03887 
03888         if (byte % 16 == 15)
03889         {
03890             edt_oc192_demux_set_mask_reg(edt_p, reg, byte);
03891             reg = 0;
03892         }
03893     }
03894 
03895     return 0;
03896 }
03912 int
03913 edt_oc192_demux_get(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
03914 
03915 {
03916     int i = 0;
03917 
03918     int n = edt_ocx_demux_nbits(line_rate);
03919 
03920     if (n == -1)
03921         return -1;
03922 
03923     for (i=0;i<12;i++)
03924     {
03925         int j;
03926 
03927         int reg = edt_oc192_demux_get_mask_reg(edt_p, i << 4);
03928 
03929         for (j=0;j<16;j++)
03930             onoff[16 * i + j] = 1 ^ (1 & (reg >> (15-j)));
03931 
03932     }
03933 
03934 
03935     return 0;
03936 
03937 }
03938 
03955 int
03956 edt_oc192_demux_chan_enable(EdtDev *edt_p, int channel, int enable)
03957 
03958 {
03959     u_short bits;
03960     int shift = (0xf - (channel & 0xf));
03961     u_short mask;
03962 
03963     mask = (u_short) (1 << shift);
03964 
03965     /* get current register value */
03966 
03967 
03968     bits = (u_short) edt_oc192_demux_get_mask_reg(edt_p,channel);
03969 
03970     /* bit sense is 0 if on, 1 if off */
03971     if (enable)
03972         bits &= ~mask;
03973     else
03974         bits |= mask;
03975 
03976     /* write back out */
03977     edt_oc192_demux_set_mask_reg(edt_p, bits, channel);
03978 
03979     return 0;
03980 }
03981 
03996 int
03997 edt_oc192_demux_get_chan_enabled(EdtDev *edt_p, int channel)
03998 
03999 {
04000     u_short bits;
04001 
04002     int shift = (0xf - (channel & 0xf));
04003     u_short mask;
04004 
04005     mask = (u_short) (1 << shift);
04006 
04007     /* get current register value */
04008     bits = (u_short) edt_oc192_demux_get_mask_reg(edt_p,channel);
04009 
04010     /* bit sense is 0 if on, 1 if off */
04011 
04012     if (bits & mask)
04013         return 0;
04014     else
04015         return 1;
04016 
04017 }
04018 
04036 int
04037 edt_ocm_demux_set(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
04038 
04039 {
04040     int n = 48;
04041     int byte = 0;
04042     u_short bits[12];
04043     u_int bitmap_reg = OCM_CH0_DEMUX_BITMAP;
04044 
04045     /* turn on all channels */
04046     memset(bits,0,sizeof(bits));
04047 
04048     switch (line_rate) {
04049         case STM1_RATE:
04050         case OC3_RATE:
04051             n = 3;
04052 
04053             break;
04054         case STM4_RATE:
04055         case OC12_RATE:
04056             n = 12;
04057             break;
04058         case STM16_RATE:
04059         case OC48_RATE:
04060             n = 48;
04061             break;
04062 
04063         default:
04064             edt_msg(EDTLIB_MSG_FATAL,"Incorrect line rate %d for OCM demux\n", line_rate);
04065             return -1;
04066 
04067     }
04068 
04069     if (edt_p->channel_no)
04070         bitmap_reg = OCM_CH1_DEMUX_BITMAP;
04071 
04072     /* cycle through oring in bits - bit 3 of byte 0 is first channel,
04073     bit 0 of last byte is last channel */
04074 
04075     /* bit sense is 0 enabled, 1 disabled */
04076 
04077     for (byte=0; byte < n; )
04078     {
04079         int val = 0;
04080         int bit;
04081 
04082         for (bit = 0;bit < 4;bit++)
04083             val = (val << 1) | ((onoff[byte++]) ? 0 : 1);
04084 
04085         val |= (((byte-1) >> 2) << 4) ;
04086 
04087         edt_reg_write(edt_p, bitmap_reg, val);
04088 
04089     }
04090 
04091     return 0;
04092 }
04109 int
04110 edt_ocm_demux_get(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
04111 
04112 {
04113     int n = 48;
04114     int i = 0;
04115     u_short bits[12];
04116     u_int bitmap_reg = OCM_CH0_DEMUX_BITMAP_READ;
04117 
04118     switch (line_rate) {
04119         case STM1_RATE:
04120         case OC3_RATE:
04121             n = 3;
04122 
04123             break;
04124         case STM4_RATE:
04125         case OC12_RATE:
04126             n = 12;
04127             break;
04128         case STM16_RATE:
04129         case OC48_RATE:
04130             n = 48;
04131             break;
04132 
04133         default:
04134             edt_msg(EDTLIB_MSG_FATAL,"Incorrect line rate %d for OCM demux\n", line_rate);
04135             return -1;
04136 
04137     }
04138 
04139     if (edt_p->channel_no)
04140         bitmap_reg = OCM_CH1_DEMUX_BITMAP_READ;
04141 
04142     for (i=0;i<(n+3)/4;i++)
04143     {
04144         edt_reg_write(edt_p, bitmap_reg, i<<4);
04145         bits[i] = (u_short) edt_reg_read(edt_p, bitmap_reg);
04146     }
04147 
04148     for (i=0;i < n; i++)
04149     {
04150         int whichbyte = i / 4;
04151         int shift = (3 - (i & 3));
04152 
04153         onoff[i] = (u_char) !(bits[whichbyte] & (1 << shift));
04154 
04155     }
04156 
04157     return 0;
04158 
04159 }
04160 
04174 int
04175 edt_ocm_demux_chan_enable(EdtDev *edt_p, int channel, int enable)
04176 
04177 {
04178     u_short bits;
04179     int whichbyte = channel / 4;
04180     int shift = (3 - (channel & 3));
04181     u_short mask;
04182     u_int bitmap_reg = OCM_CH0_DEMUX_BITMAP_READ;
04183 
04184     mask = 1 << shift;
04185     if (edt_p->channel_no)
04186         bitmap_reg = OCM_CH1_DEMUX_BITMAP_READ;
04187 
04188     /* get current register value */
04189 
04190     edt_reg_write(edt_p, bitmap_reg, whichbyte << 4);
04191     bits = edt_reg_read(edt_p, bitmap_reg) & 0xf;
04192 
04193     /* bit sense is 0 if on, 1 if off */
04194     if (enable)
04195         bits &= ~mask;
04196     else
04197         bits |= mask;
04198 
04199     /* select demux write register */
04200 
04201     bitmap_reg = (edt_p->channel_no)? OCM_CH1_DEMUX_BITMAP: OCM_CH0_DEMUX_BITMAP;
04202 
04203     bits |= (whichbyte << 4);
04204 
04205     /* write back out */
04206     edt_reg_write(edt_p, bitmap_reg, bits);
04207 
04208     return 0;
04209 }
04210 
04225 int
04226 edt_ocm_demux_get_chan_enabled(EdtDev *edt_p, int channel)
04227 
04228 {
04229     u_short bits;
04230     int whichbyte = channel / 4;
04231     int shift = (3 - (channel & 3));
04232     u_short mask;
04233     u_int bitmap_reg = OCM_CH0_DEMUX_BITMAP_READ;
04234 
04235     mask = 1 << shift;
04236     if (edt_p->channel_no)
04237         bitmap_reg = OCM_CH1_DEMUX_BITMAP_READ;
04238 
04239     /* get current register value */
04240 
04241     edt_reg_write(edt_p, bitmap_reg, whichbyte << 4);
04242     bits = edt_reg_read(edt_p, bitmap_reg) & 0xf;
04243 
04244     if (bits & mask)
04245         return 0;
04246     else
04247         return 1;
04248 
04249 }
04250 
04268 int
04269 edt_ocx_demux_set(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
04270 
04271 {
04272     if (edt_p->mezz.id == 0xffff)
04273         edt_get_board_description(edt_p, TRUE);
04274 
04275     if (edt_p->mezz.id == MEZZ_OC192 && edt_p->channel_no == 1)
04276     {
04277         return edt_oc192_demux_set(edt_p, line_rate, onoff);
04278     }
04279     else
04280     {
04281         return edt_ocm_demux_set(edt_p, line_rate, onoff);
04282     }
04283 }
04284 
04303 int
04304 edt_ocx_demux_get(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
04305 
04306 {
04307     if (edt_p->mezz.id == MEZZ_OC192 && edt_p->channel_no == 1)
04308     {
04309         return edt_oc192_demux_get(edt_p, line_rate, onoff);
04310     }
04311     else
04312     {
04313         return edt_ocm_demux_get(edt_p, line_rate, onoff);
04314     }
04315 
04316 }
04317 
04332 int
04333 edt_ocx_demux_chan_enable(EdtDev *edt_p, int channel, u_char enable)
04334 
04335 {
04336     if (edt_p->mezz.id == MEZZ_OC192 && edt_p->channel_no == 1)
04337     {
04338         return edt_oc192_demux_chan_enable(edt_p, channel, enable);
04339     }
04340     else
04341     {
04342         return edt_ocm_demux_chan_enable(edt_p, channel, enable);
04343     }
04344 }
04345 
04361 int
04362 edt_ocx_demux_get_chan_enabled(EdtDev *edt_p, int channel)
04363 
04364 {
04365     if (edt_p->mezz.id == MEZZ_OC192 && edt_p->channel_no == 1)
04366     {
04367         return edt_oc192_demux_get_chan_enabled(edt_p, channel);
04368     }
04369     else
04370     {
04371         return edt_ocm_demux_get_chan_enabled(edt_p, channel);
04372     }
04373 }
04374 
04375 /* Enables all channels */
04376 
04377 int edt_ocx_demux_reset(EdtDev *edt_p, EdtLineRate line_rate)
04378 
04379 {
04380     u_char onoff[192];
04381 
04382     memset(onoff, 1, sizeof(onoff));
04383 
04384     edt_ocx_demux_set(edt_p, line_rate, onoff);
04385     
04386     return 0;
04387 }
04388 
04389 /*
04390 * read and print the contents of the auto phase adjust that sets
04391 * up the sample point for the receive clock where the capability exists
04392 */
04393 
04394 int edt_ocx_print_auto_phase(EdtDev *edt_p)
04395 {
04396     int channel = edt_p->channel_no & 1;
04397     int base_offset = 0;
04398     int mezzanine_offset = 0;
04399     int freq = 0;
04400     u_char read_byte, ctrl_reg;
04401 
04402     FENTER("edt_ocx_print_auto_phase");
04403     if (edt_p->mezz.id == MEZZ_OCM)
04404     {
04405         if (edt_ocm_has_mezz_bitfile(edt_p, "ethernet.bit") == 0)
04406         {
04407             if (channel == 1)
04408             {
04409                 base_offset = OFFSET_CH1_BASE;
04410                 mezzanine_offset = OFFSET_CH1_MEZ;
04411             }
04412 
04413             /* write the control register to select normal status */
04414             ctrl_reg = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset);
04415             ctrl_reg &= ~STAT_SEL_MSK;
04416             ctrl_reg |= SIG_STAT;
04417             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
04418             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04419             printf("RXCLK STAT %02x -", read_byte);
04420             if (read_byte & NO_RXCLK)
04421                 printf("No receive clock present, ");
04422             else
04423                 printf("Receive clock present, ");
04424             if (read_byte & PHASE_OVF)
04425                 printf("DCM phase overflow, ");
04426             if (read_byte & DCM_LOCK_SET)
04427                 printf("DCM locked, ");
04428             else
04429                 printf("DCM not locked, ");
04430             printf("auto state is %d, sample clock is %d\n", (read_byte & DONE_STATE_MSK) >> 2,
04431                 (read_byte & (CLK_F | CLK_R)) );
04432             ctrl_reg &= ~STAT_SEL_MSK;
04433             ctrl_reg |= CLK_POS_START;
04434             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
04435             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04436             printf("First positive edge - %d\n", read_byte);
04437             ctrl_reg &= ~STAT_SEL_MSK;
04438             ctrl_reg |= CLK_NEG_EDGE;
04439             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
04440             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04441             printf("Negative edge - %d\n", read_byte);
04442             ctrl_reg &= ~STAT_SEL_MSK;
04443             ctrl_reg |= CLK_NXT_POS;
04444             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
04445             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04446             printf("Next positive edge - %d\n", read_byte);
04447             ctrl_reg &= ~STAT_SEL_MSK;
04448             ctrl_reg |= CLK_FINAL;
04449             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
04450             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04451             printf("Final auto set position - %d\n", read_byte);
04452             ctrl_reg &= ~STAT_SEL_MSK;
04453             ctrl_reg |= SHADOW_CNT;
04454             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
04455             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04456             printf("Current position - %d\n", read_byte);
04457         }
04458     }
04459 
04460     FRETURN_I("edt_ocx_print_auto_phase", 0);
04461     return 0;
04462 }
04463 
04464 /*
04465 * read frequency counter - only supported on ocm ethernet at this time
04466 * return channel bitrate in MHz
04467 */
04468 int edt_ocx_read_frequency(EdtDev *edt_p, EdtOCConfig *cfg)
04469 {
04470     int channel = edt_p->channel_no & 1;
04471     int base_offset = 0;
04472     int mezzanine_offset = 0;
04473     int freq = 0;
04474     u_char read_byte;
04475 
04476     FENTER("edt_ocx_read_frequency");
04477     if (edt_p->mezz.id == MEZZ_OCM)
04478     {
04479         if (edt_ocm_has_mezz_bitfile(edt_p, "ethernet.bit") == 0)
04480         {
04481             if (channel == 1)
04482             {
04483                 base_offset = OFFSET_CH1_BASE;
04484                 mezzanine_offset = OFFSET_CH1_MEZ;
04485             }
04486 
04487             /* write the clear bit to one  after making sure it is zero */
04488             read_byte = edt_reg_read(edt_p,  OCM_CH0_FREQ_CNT_CTRL + mezzanine_offset);
04489             read_byte &= ~CLEAR_VALID;
04490             edt_reg_write(edt_p,  OCM_CH0_FREQ_CNT_CTRL + mezzanine_offset, read_byte);
04491             read_byte |= CLEAR_VALID;
04492             edt_reg_write(edt_p,  OCM_CH0_FREQ_CNT_CTRL + mezzanine_offset, read_byte);
04493             read_byte &= ~CLEAR_VALID;
04494             edt_reg_write(edt_p,  OCM_CH0_FREQ_CNT_CTRL + mezzanine_offset, read_byte);
04495             /* wait for valid to set (100us) */
04496             while ( ((read_byte = edt_reg_read(edt_p, OCM_CH0_FREQ_STATUS + mezzanine_offset)) & FREQ_VALID) == 0) ;
04497             freq = (int) edt_reg_read( edt_p, OCM_CH0_FREQUENCY + mezzanine_offset);
04498             /* calculate frequency in MHz
04499             * Frequency counter counts 0 as the first count
04500             * the internal FPGA read  clock is divided by 4 in the SLK2511 and then by 2 in the FPGA
04501             * gate is 100us so Hz is times 10000 but MHz is divide by 100
04502             */
04503             freq = ((freq+1) * 8)/ 100; 
04504 
04505             return freq;
04506         }
04507     }
04508 
04509     FRETURN_I("edt_ocx_read_frequency",-1);
04510     return -1;
04511 }
04512 
04513 
04514 /*
04515 * change the clock phase plus or minus the amount
04516 * passed in change
04517 */
04518 int edt_ocx_rx_clk_phase(EdtDev *edt_p, int change)
04519 {
04520     int channel = edt_p->channel_no & 1;
04521     int base_offset = 0;
04522     int mezzanine_offset = 0;
04523     int current_count = 0;
04524     u_char read_byte;
04525 
04526     FENTER("edt_ocx_rx_clk_phase");
04527     if (edt_p->mezz.id == MEZZ_OCM)
04528     {
04529         if (edt_ocm_has_mezz_bitfile(edt_p, "ethernet.bit") == 0)
04530         {
04531             if (channel == 1)
04532             {
04533                 base_offset = OFFSET_CH1_BASE;
04534                 mezzanine_offset = OFFSET_CH1_MEZ;
04535             }
04536 
04537             /* read the current position from the shadow count */
04538             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset);
04539             read_byte &= ~(PRG_PS_EN | STAT_SEL_MSK) ; /* reset the ps_en if set */
04540             read_byte |= SHADOW_CNT;
04541             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04542             /* read the count */
04543             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04544             current_count = (int) (read_byte & 0xff); /* make it an int */
04545             if ( (current_count + change) < 0)
04546             {
04547                 /*
04548                 printf("Proposed RXCLK phase change %d to %d makes final < 0, setting phase to 0\n",
04549                 change, current_count);
04550                 */
04551                 change = - current_count;
04552             }
04553             if ( (current_count + change) > 255)
04554             {
04555                 /*
04556                 printf("Proposed RXCLK phase change %d to %d makes final > 255, setting phase to  max at 255\n",
04557                 change, current_count);
04558                 */
04559                 change = - current_count;
04560             }
04561             /* set to increment if change is positive  and set status read to basic status */
04562             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset);
04563             read_byte &= ~STAT_SEL_MSK ;
04564             read_byte |= SIG_STAT ; 
04565             if (change > 0) 
04566             {
04567                 read_byte |=  PRG_PS_INC;
04568             }
04569             else
04570             {
04571                 read_byte &=  ~PRG_PS_INC;
04572                 change = -change;
04573             }
04574             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04575             while(change--)
04576             {
04577                 /* inc/dec by one - strobe ps_en */
04578                 read_byte |= PRG_PS_EN;
04579                 edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04580                 read_byte &= ~PRG_PS_EN;
04581                 edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04582                 /* wait until the state machine comes back to the done state */
04583                 while (((edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset)) & DONE_STATE_MSK) != STATE_DONE);
04584             }
04585             /* read the current shadow count and return */
04586             read_byte &= ~STAT_SEL_MSK ;
04587             read_byte |= SHADOW_CNT;
04588             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04589             /* read the count */
04590             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04591             FRETURN_I("edt_ocx_rx_clk_phase", read_byte);
04592             return(read_byte);
04593         }
04594     }
04595 
04596     FRETURN_I("edt_ocx_rx_clk_phase",-1);
04597     return -1;
04598 }
04599 
04600 int
04601 edt_ocx_clear_demux(EdtOcxDemux *demux)
04602 
04603 {
04604     memset(demux, 0, sizeof(EdtOcxDemux));
04605     return 0;
04606 }
04607 
04608 int
04609 edt_ocx_parse_demux(EdtOcxDemux *demux, const char *word, char *errorstr)
04610 
04611 {
04612 
04613     u_char DCBA[4];
04614     int len = 0;
04615     int maxlen = 4;
04616     const char *cp = word;
04617     int disable = FALSE;
04618     int i;
04619     u_char *pvec;
04620     int off;
04621     u_char is_stm = TRUE;
04622 
04623     memset(DCBA,0,sizeof(DCBA));
04624 
04625     switch (demux->rate)
04626     {
04627     case 1:
04628     case 3:
04629         maxlen = 1;          
04630         break;
04631 
04632     case 4:
04633     case 12:
04634         maxlen = 2;
04635         break;
04636     case 16:
04637     case 48:
04638         maxlen = 3;
04639         break;
04640     case 64:
04641     case 192:
04642         maxlen = 4;
04643         break;
04644 
04645     case OTU2_RATE:
04646     case OTU2E_RATE:
04647     case OTU2F_RATE:
04648         maxlen = 1;
04649         is_stm = FALSE;
04650         break;
04651 
04652     default:
04653         sprintf(errorstr, "Rate %d not defined for demux\n",demux->rate);
04654         return -1;
04655 
04656     }
04657 
04658     /* remove parens and commas */
04659 
04660     if (*cp == '-') 
04661     {
04662         disable = TRUE;
04663         cp++;
04664     }
04665 
04666     if (*cp == '(')
04667         cp++;
04668 
04669     while (*cp && *cp != ')' && len < 4)
04670     {
04671         if (*cp >= '0' && *cp <= '4')
04672         {
04673             DCBA[len] = *cp - '0';
04674             len++;
04675         }
04676         else
04677         {
04678             sprintf(errorstr, "Unexpected character %c at %d in %s, should be 0-4\n",
04679                 *cp, cp - word, word);
04680             return -1;
04681 
04682         }
04683 
04684         cp++;
04685         if (*cp == ',')
04686             cp++;
04687         else if (*cp && *cp != ')')
04688         {
04689             sprintf(errorstr, "Unexpected character %c at %d in %s\n",
04690                 *cp, cp - word, word);
04691             return -1;
04692         }
04693     }
04694 
04695 
04696     if (len > maxlen)
04697     {
04698         sprintf(errorstr, "%s can only have %d value%s in notation\n", edt_ocx_rate_name(demux->rate),maxlen,(maxlen > 1)?"s":"");
04699         return -1;
04700     }
04701 
04702     if (is_stm)
04703     {
04704         if (DCBA[maxlen-1] == 4)
04705         {
04706             sprintf(errorstr, "%s last value should be 1-3 in %s\n", edt_ocx_rate_name(demux->rate), word);
04707             return -1;
04708         }
04709     }
04710 
04711     sprintf(errorstr, "DCBA = (");
04712     for (i=0;i<maxlen-1;i++)
04713         sprintf(errorstr + strlen(errorstr), "%d,", DCBA[i]);
04714     sprintf(errorstr + strlen(errorstr), "%d)\n", DCBA[maxlen-1]);
04715 
04716     if (disable)
04717         pvec = demux->disable;
04718     else
04719         pvec = demux->enable;
04720 
04721     switch (demux->rate)
04722     {
04723     case 1:
04724     case 3:
04725         break;
04726 
04727     case 4:
04728     case 12:
04729         if (DCBA[0] == 0)
04730         {
04731             for (i=0;i<12;i++)
04732                 pvec[i] = 1;
04733         }
04734         else if (DCBA[1] == 0)
04735         {
04736             /* STM-1 (vC-4) */
04737             off = (DCBA[0]-1);
04738             pvec[off] = 1;
04739             pvec[off+4] = 1;
04740             pvec[off+8] = 1;
04741             sprintf(errorstr + strlen(errorstr), "STM-1 # %d\n", off+1);
04742         }
04743         else
04744         {
04745             off = (DCBA[0]-1) + 4 * (DCBA[1]-1);
04746             pvec[off] = 1;
04747             sprintf(errorstr + strlen(errorstr), "STM-0 # %d\n", off+1);
04748         }
04749         break;
04750 
04751     case 16:
04752     case 48:
04753         if (DCBA[0] == 0)
04754         {
04755             for (i=0;i<48;i++)
04756                 pvec[i] = 1;
04757         }
04758         else if (DCBA[1] == 0)
04759         {
04760             /* STM-4 (vC-4-4c) */
04761             off = 4 * (DCBA[0]-1);
04762             for (i=0;i<4;i++)
04763             {
04764                 pvec[off+i] = 1;
04765                 pvec[off+16+i] = 1;
04766                 pvec[off+32+i] = 1;
04767             }
04768             sprintf(errorstr + strlen(errorstr), "STM-4 # %d\n", off/4 + 1);
04769         }
04770         else if (DCBA[2] == 0)
04771         {
04772             /* STM-1 (vC-4) */
04773             off = 4 * (DCBA[0]-1) + (DCBA[1]-1);
04774             pvec[off] = 1;
04775             pvec[off+16] = 1;
04776             pvec[off+32] = 1;
04777             sprintf(errorstr + strlen(errorstr), "STM-1 # %d\n", off+1);
04778         }
04779         else
04780         {
04781             off = 4 * (DCBA[0]-1) + (DCBA[1]-1) + 16 * (DCBA[2]-1);
04782             pvec[off] = 1;
04783             sprintf(errorstr + strlen(errorstr), "STM-0 # %d\n", off+1);
04784         }
04785         break;
04786 
04787     case 64:
04788     case 192:
04789         if (DCBA[0] == 0)
04790         {
04791             for (i=0;i<192;i++)
04792                 pvec[i] = 1;
04793             sprintf(errorstr + strlen(errorstr), "STM-64 \n");
04794         }
04795         else if (DCBA[1] == 0)
04796         {
04797             /* STM-16 (vC-4-16c) */
04798             off = 16 * (DCBA[0]-1);
04799             for (i=0;i<16;i++)
04800             {
04801                 pvec[off+i] = 1;
04802                 pvec[off+64+i] = 1;
04803                 pvec[off+128+i] = 1;
04804             }     
04805             sprintf(errorstr + strlen(errorstr), "STM-16 # %d\n", off / 16 + 1);
04806         }
04807         else if (DCBA[2] == 0)
04808         {
04809             /* STM-4 (vC-4-4c) */
04810             off = 16 * (DCBA[0]-1) + 4 * (DCBA[1]-1);
04811             for (i=0;i<4;i++)
04812             {
04813                 pvec[off+i] = 1;
04814                 pvec[off+64+i] = 1;
04815                 pvec[off+128+i] = 1;
04816             }
04817             sprintf(errorstr + strlen(errorstr), "STM-4 # %d\n", off/4 + 1);
04818         }
04819         else if (DCBA[3] == 0)
04820         {
04821             /* STM-1 (vC-4) */
04822             off = 16 * (DCBA[0]-1) + 4 * (DCBA[1]-1) + (DCBA[2]-1);
04823             pvec[off] = 1;
04824             pvec[off+64] = 1;
04825             pvec[off+128] = 1;
04826             sprintf(errorstr + strlen(errorstr), "STM-1 # %d\n", off+1);
04827         }
04828         else
04829         {
04830             off = 16 * (DCBA[0]-1) + 4 * (DCBA[1]-1) + (DCBA[2]-1) + 64 * (DCBA[3]-1);
04831             pvec[off] = 1;
04832             sprintf(errorstr + strlen(errorstr), "STM-0 # %d\n", off+1);
04833         }
04834         break;
04835 
04836     case OTU2_RATE:
04837     case OTU2E_RATE:
04838     case OTU2F_RATE:
04839         off = DCBA[0]-1;
04840         pvec[off] = 1;
04841         pvec[off+4] = 1;
04842         pvec[off+8] = 1;
04843         pvec[off+12] = 1;
04844 
04845         break;
04846 
04847     }
04848 
04849     return 0;
04850 }
04851 
04852 char * edt_ocx_print_byte_array(u_char *pvec, EdtLineRate rate, char *buf)
04853 
04854 {
04855     int n = edt_ocx_demux_nbits(rate);
04856 
04857     static char pbuf[256];
04858 
04859     int on = 0;
04860     int start = 0;
04861     char *bp;
04862 
04863     int i;
04864 
04865     if (buf == NULL)
04866         buf = pbuf;
04867 
04868     bp = buf;
04869 
04870     for (i=0;i<n;i++)
04871     {
04872         if ((pvec[i] &&  !on) ||
04873             (!pvec[i] && on))
04874         {
04875             if (on)
04876             {
04877                 if (start == i-1)
04878                     sprintf(bp, "%d ", i-1);
04879                 else
04880                     sprintf(bp, "%d-%d ", start, i-1);
04881                 bp += strlen(bp);
04882             }
04883             else
04884             {
04885                 start = i;
04886             }
04887 
04888             on = !on;
04889         }
04890         else if ((i == n-1) && on)
04891         {
04892             sprintf(bp, "%d-%d ", start, i);
04893             bp += strlen(bp);
04894 
04895         }
04896     }
04897 
04898     return buf;
04899 
04900 }
04901 
04902 
04903 
04904 int edt_ocx_demux_print(EdtOcxDemux *demux)
04905 
04906 {
04907     char buf[256];
04908 
04909 
04910     printf("Current  : %s\n",edt_ocx_print_byte_array(demux->current_values, demux->rate, buf));
04911     printf("Enable   : %s\n",edt_ocx_print_byte_array(demux->enable, demux->rate, buf));
04912     printf("Disable  : %s\n",edt_ocx_print_byte_array(demux->disable,demux->rate, buf));
04913 
04914     return 0;
04915 
04916 }
04917 
04918 
04919 
04920 double edt_ocx_get_data_rate(EdtLineRate rate)
04921 
04922 {
04923     double r = 1000000.0;
04924     switch (rate)
04925     {
04926     case STM0_RATE:
04927         r *= 4.86;
04928         break;
04929 
04930     case GIGE_RATE:
04931         r *= 125.0;
04932         break;
04933 
04934     case OC3_RATE:
04935     case STM1_RATE:
04936         r *= 19.44;
04937         break;
04938 
04939     case OC12_RATE:
04940     case STM4_RATE:
04941         r *= 77.76;
04942         break;
04943 
04944     case OC48_RATE:
04945     case STM16_RATE:
04946         r *= 311.04;
04947         break;
04948 
04949     case OTU1_RATE:
04950         r *= 333.26;
04951         break;
04952 
04953     case OC192_RATE:
04954     case STM64_RATE: 
04955         r *= 1244.16;
04956         break;
04957 
04958     case GIG10E_RATE:
04959         r *= 1289.06;
04960         break;
04961 
04962     case OTU2_RATE:
04963         r *= 1338.65;
04964         break;
04965 
04966     case OTU2E_RATE:
04967         r *= 1386.96;
04968         break;
04969 
04970     }
04971 
04972     return r;
04973 }

Generated on 19 Jun 2015 by  doxygen 1.4.7