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 
00102 /***************************************
00103 * Some utility functions
00104 * These probably ought to go in a general
00105 * library file
00106 **************************************/
00107 
00108 #if 1
00109 
00110 int
00111 edt_reg_set_bitmask(EdtDev *edt_p, u_int reg, u_int mask, int state)
00112 
00113 {
00114 
00115     return  (state)? edt_reg_or(edt_p, reg, mask) : edt_reg_and(edt_p, reg, ~mask);
00116 }
00117 
00118 #else
00119 
00120 #define edt_reg_set_bitmask(edt_p, reg, mask, state) \
00121     ((state)? edt_reg_or(edt_p, reg, mask) : edt_reg_and(edt_p, reg, ~mask))
00122 
00123 #endif
00124 
00125 
00126 int
00127 edt_wait_register_bits_low(EdtDev *edt_p, u_int reg, u_int mask, int timeout)
00128 
00129 {
00130     int t = 0;
00131 
00132     while ((t < timeout || !timeout) && (edt_reg_read(edt_p,reg) & mask))
00133     {
00134         edt_msleep(100);
00135         t += 100;
00136     }
00137 
00138     return (t >= timeout && (timeout != 0));
00139 }
00140 
00141 
00142 int
00143 edt_wait_register_bits_high(EdtDev *edt_p, u_int reg, u_int mask, int timeout)
00144 
00145 {
00146     int t = 0;
00147 
00148     while ((t < timeout || !timeout) && 
00149         !((edt_reg_read(edt_p,reg) & mask)==mask))
00150     {
00151         edt_msleep(100);
00152         t += 100;
00153     }
00154 
00155     /* fixed bug where t == timeout does not return error -mcm 11/25/08 */
00156     return (t >= timeout && (timeout != 0));
00157 
00158 }
00159 
00160 void
00161 edt_ocx_clear_state_flag(EdtOCConfig *cfg, const u_int flag)
00162 
00163 {
00164     cfg->state &= ~flag;
00165 }
00166 
00167 void
00168 edt_ocx_set_state_flag(EdtOCConfig *cfg, const u_int flag)
00169 
00170 {
00171     cfg->state |= ~flag;
00172 }
00173 
00174 /**********************************
00175 * These functions work the same 
00176 * on both OCM and OC192
00177 **********************************/
00178 
00188 void
00189 edt_ocx_enable_framing_errors(EdtDev *edt_p, int state)
00190 
00191 {
00192 
00193     u_int mezzanine_offset = 0;
00194 
00195     if (edt_p->channel_no & 1)
00196     {
00197         mezzanine_offset = OFFSET_CH1_MEZ;
00198     }
00199 
00200     edt_reg_set_bitmask(edt_p, OCM_CH0_CNT_CTRL + mezzanine_offset,
00201         OCM_EN_ERROR_COUNT, state);
00202 
00203 }
00204 
00205 
00218 int 
00219 edt_ocx_get_framing_errors(EdtDev *edt_p, EdtOCXFrameErrors *err_p)
00220 
00221 {
00222     u_int mezzanine_offset = 0;
00223 
00224     if (edt_p->channel_no & 1)
00225     {
00226         mezzanine_offset = OFFSET_CH1_MEZ;
00227     }
00228     /* Assume frame counts are enabled */
00229 
00230     edt_reg_set_bitmask(edt_p, OCM_CH0_CNT_CTRL + mezzanine_offset , 
00231         OCM_ERROR_COUNT_HOLD, 1);
00232 
00233     err_p->b1_errors = edt_reg_read(edt_p, 
00234         OCM_CH0_B1_ERROR_CNT + mezzanine_offset);
00235     err_p->b1_error_mask = (u_char) edt_reg_read(edt_p, 
00236         OCM_CH0_B1_ERROR_MASK + mezzanine_offset);
00237     err_p->b2_errors = edt_reg_read(edt_p, 
00238         OCM_CH0_B2_ERROR_CNT + mezzanine_offset);
00239     err_p->m1_errors = edt_reg_read(edt_p, 
00240         OCM_CH0_M1_ERROR_CNT + mezzanine_offset);
00241     err_p->lof_errors = edt_reg_read(edt_p, 
00242         OCM_CH0_LOF_CNT + mezzanine_offset);
00243     err_p->frame_pattern_errors = edt_reg_read(edt_p, 
00244         OCM_CH0_FRM_PAT_CNT + mezzanine_offset);
00245     err_p->false_frame_errors = edt_reg_read(edt_p, 
00246         OCM_CH0_FALSE_FRM_CNT + mezzanine_offset);
00247 
00248     edt_reg_set_bitmask(edt_p, OCM_CH0_CNT_CTRL + mezzanine_offset , 
00249         OCM_ERROR_COUNT_HOLD, 0);
00250 
00251     return 0;
00252 }
00253 
00254 
00268 int
00269 edt_ocx_lock_local_clock(EdtDev *edt_p, int timeout)
00270 
00271 {
00272 
00273     FENTER("edt_ocx_lock_clocks");
00274 
00275     if (edt_wait_register_bits_high(edt_p, PCD_STAT, LOCAL_SYS_LOCK,timeout))
00276     {
00277         edt_msg(EDTLIB_MSG_FATAL,"\rBaseboard System clock not locked");
00278         return -1;
00279     }
00280 
00281     edt_msg(EDTLIB_MSG_INFO_1,"Local System clocks locked \n");
00282 
00283     return 0;
00284 
00285 }
00286 
00301 int
00302 edt_ocx_lock_channel_clock(EdtDev *edt_p, int channel, int timeout)
00303 
00304 {
00305     int base_offset;
00306 
00307     FENTER("edt_ocx_lock_clocks");
00308 
00309     base_offset = (channel & 1) ? OFFSET_CH1_BASE:0;
00310 
00311     if (edt_wait_register_bits_high (edt_p, OCM_CH0_ENABLE + base_offset,
00312         SYS_LOCK,timeout))
00313     {
00314         edt_msg(EDTLIB_MSG_FATAL,"\rMezzanine System clock not locked");
00315         return -1;
00316 
00317     }
00318 
00319     return 0;
00320 
00321 }
00322 
00337 int
00338 edt_msdv_load_default_mezzanine(EdtDev *edt_p, char *mezz_0)
00339 
00340 {
00341     int rc = 0;
00342 
00343     char *bitname = "dvb_asi.bit";
00344 
00345     if (mezz_0)
00346         if (mezz_0[0])
00347             bitname = mezz_0;
00348 
00349     rc = edt_bitload(edt_p, NULL, bitname, BITLOAD_FLAGS_MEZZANINE, 0);
00350 
00351     return rc;
00352 }
00353 
00368 int
00369 edt_net10g_load_default_mezzanine(EdtDev *edt_p, char *mezz_0, char *mezz_1)
00370 
00371 {
00372     int rc = 0;
00373 
00374     char *bitname = "net10g_5v_sdh.bit";
00375 
00376     FENTER("edt_net10g_load_default_mezzanine");
00377     if (mezz_0)
00378         if (mezz_0[0])
00379             bitname = mezz_0;
00380 
00381     rc = edt_bitload(edt_p, NULL, bitname, BITLOAD_FLAGS_MEZZANINE, 0);
00382 
00383     if (rc == 0)
00384     {
00385         bitname = "net10g_s3_cfg.bit";
00386 
00387         if (mezz_1)
00388             if (mezz_1[0])
00389                 bitname = mezz_1;
00390 
00391         rc = edt_bitload(edt_p, NULL, bitname, BITLOAD_FLAGS_MEZZANINE | BITLOAD_FLAGS_CH1, 0);
00392     }
00393 
00394     return rc;
00395 }
00396 
00397 /***************************************
00398 *
00399 * OCM specific functions
00400 * Most have equivalent OC192 functions
00401 *
00402 **************************************/
00403 
00414 int
00415 edt_ocm_lock_clocks(EdtDev *edt_p, int timeout)
00416 
00417 {
00418 
00419     if (edt_ocx_lock_local_clock(edt_p, timeout) ||
00420         edt_ocx_lock_channel_clock(edt_p, 0, timeout) ||
00421         edt_ocx_lock_channel_clock(edt_p, 1, timeout))
00422 
00423         return -1;
00424 
00425     edt_msg(EDTLIB_MSG_INFO_1,"All System clocks locked          \n");
00426 
00427     return 0;
00428 
00429 }
00430 
00431 
00443 const char *
00444 edt_ocm_mezz_filename(EdtDev *edt_p, EdtLineRate line_rate)
00445 
00446 {
00447 
00448     char *target_bitfile;
00449 
00450     switch (line_rate) {
00451         case OC3_RATE:      
00452         case OC12_RATE:     
00453         case STM1_RATE:
00454         case STM4_RATE:
00455             target_bitfile="ocm12.bit";
00456             break;
00457 
00458         case STM16_RATE:            
00459         case OC48_RATE:     
00460             target_bitfile="ocm48.bit";
00461             break;
00462 
00463         case GIGE_RATE:
00464             target_bitfile="ethernet.bit";
00465             break;
00466 
00467         default:
00468             target_bitfile = NULL;
00469 
00470     }
00471 
00472     return target_bitfile;
00473 }
00474 
00492 int
00493 edt_ocm_load_default_mezzanine(EdtDev *edt_p, 
00494                                EdtLineRate line_rate,
00495                                char *mezz_0,
00496                                char *mezz_1)
00497 
00498 {
00499 
00500     int rc = 0;
00501     int flags  = BITLOAD_FLAGS_OVR | BITLOAD_FLAGS_OCM;
00502     int rate = OC48_RATE;
00503 
00504     const char *bitname;
00505 
00506     if (edt_p->channel_no == 0)
00507         rate = (line_rate)?line_rate:OC48_RATE;
00508 
00509     if (mezz_0 && mezz_0[0])
00510         bitname = mezz_0;
00511     else
00512         bitname = edt_ocm_mezz_filename(edt_p, rate);
00513 
00514     rc = edt_bitload(edt_p, NULL, bitname, flags, 0);
00515 
00516     if (rc == 0)
00517     {
00518         flags |= BITLOAD_FLAGS_CH1;
00519 
00520         if (mezz_1 && mezz_1[0])
00521             bitname = mezz_1;
00522         else
00523             bitname = edt_ocm_mezz_filename(edt_p, OC12_RATE);
00524 
00525         rc = edt_bitload(edt_p, NULL, bitname, flags, 0);
00526 
00527     }
00528 
00529     return rc;
00530 
00531 }
00532 
00545 int
00546 edt_ocm_speed_capable(int channel, EdtLineRate line_rate)
00547 
00548 {
00549     int rc = -1;
00550     switch (line_rate) {
00551         case STM1_RATE:
00552         case STM4_RATE:
00553         case OC3_RATE:      
00554         case OC12_RATE:     
00555         case GIGE_RATE:
00556         case STM16_RATE:            
00557         case OC48_RATE:     
00558             rc = 0;
00559             break;
00560 
00561         case GIG10E_RATE:
00562         case OTU2_RATE:
00563         case STM64_RATE:
00564         case OC192_RATE:
00565             rc =  -1;
00566             break;
00567 
00568         default:
00569             edt_msg(EDTLIB_MSG_FATAL,"Unknown bit rate %d\n", line_rate);
00570             rc =  -1;
00571 
00572     } 
00573     return rc;
00574 }
00575 
00576 
00577 
00591 int
00592 edt_ocm_has_mezz_bitfile(EdtDev *edt_p, const char *bitfile_name)
00593 
00594 {
00595     int channel = edt_p->channel_no & 1;
00596     char *ch_id;
00597     int rc;
00598 
00599     FENTER_S("edt_ocm_has_correct_bitfile",bitfile_name);
00600 
00601     if (channel == 0)
00602     {
00603         ch_id  = edt_p->bfd.mezz_name0;
00604     }
00605     else
00606     {
00607         ch_id  = edt_p->bfd.mezz_name1;
00608     }
00609 
00610     /* check correct bitfile for channel 0 */
00611     rc = strcmp(ch_id, bitfile_name);
00612 
00613     FRETURN_I("edt_ocm_has_correct_bitfile",rc);
00614 
00615     return rc;
00616 
00617 }
00631 int
00632 edt_ocm_set_clock_select(EdtDev *edt_p, EdtLineRate line_rate)
00633 
00634 {
00635     int channel = edt_p->channel_no & 1;
00636     int clk_select = CLK_SONET_SDH;
00637     int clk_val = OC3_STM1;
00638     int base_offset = 0;
00639     int mezzanine_offset = 0;
00640     int read_byte;
00641 
00642 
00643     FENTER_I("edt_ocm_set_clock_select", line_rate);
00644 
00645     switch (line_rate)
00646     {
00647     case OC3_RATE:          
00648     case STM1_RATE:
00649         clk_val = OC3_STM1;
00650         break;
00651 
00652     case OC12_RATE:      
00653     case STM4_RATE:
00654         clk_val = OC12_STM4;
00655         break;
00656 
00657     case STM16_RATE:        
00658     case OC48_RATE:         
00659         clk_val = OC48_STM16;
00660         break;
00661 
00662     case GIGE_RATE:
00663         clk_val = OC24;
00664         clk_select = CLK_GE | 0x4;
00665         break;
00666 
00667     }
00668 
00669     if (channel == 1) 
00670     {
00671         base_offset = OFFSET_CH1_BASE;
00672         mezzanine_offset = OFFSET_CH1_MEZ;
00673     }
00674 
00675     /* select the oscillator frequency */
00676     read_byte = edt_reg_read(edt_p, OCM_TX_CONFIG + mezzanine_offset); 
00677     read_byte &= ~CLOCK_SEL_MSK;
00678     read_byte |= clk_select;
00679     edt_reg_write(edt_p, OCM_TX_CONFIG + mezzanine_offset, read_byte );
00680     /* set LIU to correct multiplier */
00681     read_byte = edt_reg_read(edt_p, OCM_CH0_CONFIG0 + base_offset);  
00682     read_byte &= ~RX_SEL_MSK;
00683     read_byte |= clk_val;
00684     edt_reg_write(edt_p, OCM_CH0_CONFIG0 + base_offset , read_byte);  
00685 
00686 
00687     FRETURN("edt_ocm_set_clock_select");
00688 
00689     return 0;
00690 
00691 }
00692 
00708 int
00709 edt_ocm_channel_lock_frontend(EdtDev *edt_p, EdtOCConfig *cfg)
00710 
00711 {
00712     int done = 0;
00713     /* it takes 200 ms every time through */
00714 
00715     int timeout = cfg->timeout;
00716     int timer = 0;
00717     int timed_out = 0;
00718 
00719     uint_t base_offset = 0;
00720     uint_t mezzanine_offset = 0;
00721     int channel = edt_p->channel_no & 1;
00722 
00723     if (channel == 1)
00724     {
00725         base_offset = OFFSET_CH1_BASE;
00726         mezzanine_offset = OFFSET_CH1_MEZ;
00727 
00728     }
00729     /* Reset front end DPLLs */
00730     edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset,  ~(SLK_EN | PLL_EN));
00731 
00732     edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, SYS_EN);
00733 
00734     if (cfg->flags & EDT_OCX_ENABLE_MEM && (edt_p->channel_no == 0))
00735         edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, RAM_EN );
00736     else
00737         edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~RAM_EN );
00738 
00739     if (cfg->flags & EDT_OCX_PRBS_EN)
00740     {
00741         edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, PLL_EN);
00742         return 0;
00743     }
00744 
00745     if (!(cfg->flags & EDT_OCX_NO_SIG_DET))
00746     {
00747         timer = 0;
00748         timed_out = 0;
00749         while (!edt_ocx_channel_signal_detect(edt_p) && !timed_out)
00750         {
00751             edt_msg(EDT_MSG_WARNING,"\rChannel %d no signal detected -  check signal input", channel);
00752             edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~(SLK_EN | PLL_EN));
00753             /* always imcrement timer at least one */
00754             timer ++;   
00755             if (timeout)
00756                 timed_out = timer >= timeout;
00757         }  
00758 
00759     }
00760 
00761     if (timed_out)
00762     {
00763         edt_msg(EDT_MSG_FATAL,"\rChannel %d no signal detected -  check signal input", channel);
00764         return -1;
00765     }
00766 
00767     timer = 0;
00768     timed_out = 0;
00769 
00770     while (done == 0 && !timed_out)
00771     {
00772         /* enable SLK */
00773         edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, SLK_EN); 
00774         edt_msleep(100); /* wait for the DCM to lock */
00775         timer += 100;
00776         /* test if SLK is locked */
00777         /* LOL is a reliable indication of some lock problems but not all */
00778         if ((edt_reg_read(edt_p, OCM_CH0_STATUS + base_offset) & LOL) == 0)
00779         {
00780             edt_reg_or(edt_p, OCM_CH0_ENABLE + base_offset, PLL_EN); 
00781             edt_msleep(100); /* wait for the DCM to lock */
00782             timer += 100;
00783             if ((done = (edt_reg_read(edt_p, OCM_CH0_ENABLE + base_offset) & RX_LOCK)) == 0)
00784             {
00785                 edt_msg(EDT_MSG_WARNING,"\rChannel %d FPGA PLL not locked check signal input type", channel);
00786                 /* reset slk and dcm enable */
00787                 edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~(SLK_EN | PLL_EN));
00788             }
00789         }
00790         else
00791         {
00792             edt_msg(EDT_MSG_WARNING,"\rChannel %d LIU PLL not locked check signal input type", channel);
00793             /* reset slk and dcm enable */
00794             edt_reg_and(edt_p, OCM_CH0_ENABLE + base_offset, ~(SLK_EN | PLL_EN));
00795         }
00796 
00797         if (timeout)
00798             timed_out = timer >= cfg->receive_dcm_timeout;
00799 
00800     }
00801 
00802     if (timed_out)
00803     {
00804         edt_msg(EDT_MSG_FATAL,"\rChannel %d unable to lock PLL -  check signal input", channel);
00805         return -1;
00806     }
00807     else
00808         edt_msg(EDT_MSG_INFO_1,"\rChannel %d PLL locked                    \n", channel);
00809 
00810 
00811     return 0;
00812 
00813 }
00831 int
00832 edt_ocm_channel_setup(EdtDev *edt_p, EdtOCConfig *cfg)
00833 
00834 
00835 {
00836     int channel = edt_p->channel_no;
00837     int base_offset = 0;
00838     int mezzanine_offset = 0;
00839     u_char rx_ctrl ;
00840     u_char rx_filter ;
00841 
00842     FENTER("edt_ocm_channel_setup");
00843 
00844     if (edt_p->mezz.id == MEZZ_OC192)
00845     {
00846         edt_reg_write(edt_p, OC192_CHAN_SELECT, 0);     
00847     }
00848 
00849 
00850     if (channel == 1)
00851     {
00852         base_offset = OFFSET_CH1_BASE;
00853         mezzanine_offset = OFFSET_CH1_MEZ;
00854 
00855     }
00856 
00857     /* set local loopback if requested */
00858     edt_reg_set_bitmask(edt_p, OCM_CH0_CONFIG0 + base_offset, LOCAL_LOOP, (cfg->flags & EDT_OCX_LOOPBACK));
00859 
00860     /* set remote loopback if requested */
00861     edt_reg_set_bitmask(edt_p, OCM_CH0_CONFIG0 + base_offset, REMOTE_LOOP, (cfg->flags & EDT_OCX_REMOTE_LPBK));
00862 
00863     /* set LIU PRBS7 generator if requested */
00864     edt_reg_set_bitmask(edt_p, OCM_CH0_CONFIG0 + base_offset, PRBS_EN, (cfg->flags & EDT_OCX_PRBS_EN));
00865 
00866 
00867     rx_ctrl = (u_char) edt_reg_read(edt_p, OCM_RX_CTRL + mezzanine_offset);
00868 
00869     if (cfg->flags & EDT_OCX_FRAMED)
00870     {
00871         rx_ctrl |= FRAME_EN;
00872         if ((cfg->flags & EDT_OCX_DESCRAMBLE) == 0)
00873             rx_ctrl |= DISABLE_SCRAM;
00874         else
00875             rx_ctrl &= ~DISABLE_SCRAM;
00876     }
00877     else
00878         rx_ctrl &= ~FRAME_EN;
00879 
00880     if (cfg->flags & EDT_OCX_ENABLE_MEM)
00881         rx_ctrl |= RX_DATA_SRC_2G;
00882     else
00883         rx_ctrl &= ~RX_DATA_SRC_2G;
00884 
00885     edt_reg_write(edt_p, OCM_RX_CTRL + mezzanine_offset, rx_ctrl); 
00886 
00887     rx_filter = (u_char) edt_reg_read(edt_p, OCM_RX_FILTER + mezzanine_offset);
00888     rx_filter &= ~OVERHEAD_ONLY; 
00889     if (cfg->flags & EDT_OCX_OVHD_ONLY) 
00890     {
00891         if (cfg->flags & EDT_OCX_FRAMED)
00892             rx_filter |= OVERHEAD_ONLY; 
00893         else
00894             edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
00895     }
00896     /* enable data substitution */
00897     rx_filter &= ~(EN_DATA_COUNTER | COUNT_FREERUN); 
00898     if (cfg->flags &  EDT_OCX_ENABLE_COUNT_DATA) 
00899         rx_filter |= EN_DATA_COUNTER;
00900     if (cfg->flags & EDT_OCX_FREERUN_COUNT_DATA)
00901         rx_filter |= COUNT_FREERUN;
00902     /* enable all bytes from ethernet 8b/10b decoder */
00903     rx_filter &= ~(EN_ALL_DECODED); 
00904     if (cfg->flags & EDT_OCX_ETHERNET_ALL_DECODE)
00905         rx_filter |= EN_ALL_DECODED;
00906     edt_reg_write(edt_p, OCM_RX_FILTER + mezzanine_offset, rx_filter); 
00907 
00908     FRETURN_I("edt_ocm_channel_setup",0);
00909     return 0;
00910 }
00911 
00923 int
00924 edt_ocm_wait_for_frame(EdtDev *edt_p, int timeout)
00925 
00926 {
00927     u_int cfg;
00928     int mezzanine_offset = 0;
00929     int t = 100;
00930     int rc = 0;
00931 
00932     FENTER("edt_ocm_wait_for_frame");
00933 
00934     if (edt_p->channel_no == 1)
00935     {
00936         mezzanine_offset = OFFSET_CH1_MEZ;
00937     }
00938 
00939     edt_msg(EDTLIB_MSG_INFO_1,"Waiting for frame CH%d", edt_p->channel_no);
00940 
00941     edt_msleep(100);
00942 
00943     while (((cfg = edt_reg_read(edt_p, OCM_RX_STATUS + mezzanine_offset)) & FRAMED) == 0 &&
00944         t < timeout)
00945     {
00946         edt_msg(EDTLIB_MSG_INFO_1,".");
00947         cfg = edt_reg_read(edt_p, OCM_RX_CTRL + mezzanine_offset);
00948         edt_reg_write(edt_p, OCM_RX_CTRL + mezzanine_offset, cfg | RESET_FRM);  /* set reset frame */
00949         edt_reg_write(edt_p, OCM_RX_CTRL + mezzanine_offset, cfg);  /* clear it */
00950         edt_msleep(100);
00951         t += 100;
00952     }
00953 
00954     if (t < timeout)
00955         edt_msg(EDTLIB_MSG_INFO_1," framed\n");
00956     else
00957     {
00958         edt_msg(EDTLIB_MSG_FATAL," Framing timed out in %d ms\n", timeout);
00959         rc = -1;
00960     }
00961 
00962     FRETURN_I("edt_ocm_wait_for_frame", rc);
00963 
00964     return rc;
00965 
00966 }
00967 
00968 /***************************************
00969 *
00970 * OC192 board-specific functions
00971 * Most other than the _mdio_ access functions
00972 * have an euqivalent OCM function
00973 *
00974 **************************************/
00975 
00976 /***************************************
00977 *
00978 * OC192 mdio functions to talk to the LIU
00979 *
00980 **************************************/
00981 
00982 
00995 unsigned char 
00996 edt_oc192_mdio_read(EdtDev *edt_p, unsigned char address)
00997 {
00998     unsigned char result=0, byte;
00999     unsigned int val;
01000     int i;
01001 
01002     FENTER_I("edt_oc192_mdio_read",address);
01003     val = 0x60000000;
01004     val |= ((unsigned int) (address & 0x1f))<<18;
01005     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI);
01006     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01007     result = 0;
01008     for (i=31; i>=0; i--) {
01009         if (i>17) {
01010             if (!((val>>i) & 0x1)) {
01011                 edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01012                 edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK | SCLK_TRI);
01013             } else {
01014                 edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01015                 edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01016             }
01017             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01018         } else {
01019             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK_TRI);
01020             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK | SCLK_TRI);
01021             if (i<=8 && i>=1) {
01022                 byte = edt_intfc_read(edt_p, OC192_LIU_MDIO_BUS) & SDATA_IN;
01023                 result |= ((byte>>4)<<(i-1));
01024             }
01025         }
01026     }
01027     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK_TRI);
01028     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK | SCLK_TRI);
01029     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SCLK);
01030     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, 0);
01031 
01032     FRETURN_I("edt_oc192_mdio_read",result);
01033     return result;
01034 }
01035 
01047 void
01048 edt_oc192_mdio_write(EdtDev *edt_p, unsigned char address, unsigned char value)
01049 {
01050     unsigned int val;
01051     int i;
01052 
01053     FENTER_I_I("edt_oc192_mdio_write",address, value);
01054     val = 0x50020000;
01055     val |= ((((unsigned int) (address & 0x1f))<<18) | (unsigned int) value);
01056     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI);
01057     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01058     for (i=31; i>=0; i--) {
01059         if (!((val>>i)&0x1)) {
01060             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK_TRI);
01061             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_TRI | SCLK | SCLK_TRI);
01062         } else {
01063             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01064             edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01065         }
01066     }
01067     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01068     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01069     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01070     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01071 
01072     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SCLK) ;
01073     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, 0);
01074     FRETURN("edt_oc192_mdio_write");
01075 }
01076 
01085 void 
01086 edt_oc192_mdio_init(EdtDev *edt_p)
01087 {
01088     int i;
01089 
01090     FENTER("edt_oc192_mdio_init");
01091 
01092     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI);
01093     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01094     for (i=32; i>=0; i--) {
01095         edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK_TRI);
01096         edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SDATA_TRI | SCLK | SCLK_TRI);
01097     }
01098     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, SDATA_OUT | SCLK);
01099     edt_intfc_write(edt_p, OC192_LIU_MDIO_BUS, 0);
01100     FRETURN("edt_oc192_mdio_init");
01101 }
01102 
01110 void
01111 edt_oc192_reset_liu(EdtDev *edt_p)
01112 
01113 {
01114     FENTER("edt_oc192_reset_liu");
01115     /* Reset the AMCC S19235 */
01116     edt_intfc_write(edt_p, OC192_ENABLE, edt_intfc_read(edt_p, OC192_ENABLE) | AMCC_RST);
01117     edt_msleep(100);
01118     edt_intfc_write(edt_p, OC192_ENABLE, edt_intfc_read(edt_p, OC192_ENABLE) & ~AMCC_RST);
01119     edt_msleep(100);
01120     edt_oc192_mdio_init(edt_p);
01121     FRETURN("edt_oc192_reset_liu");
01122 }
01123 
01131 void
01132 edt_oc192_mdio_set_clock(EdtDev *edt_p)
01133 
01134 {
01135 
01136 }
01137 
01147 void
01148 edt_oc192_mdio_set_swap(EdtDev *edt_p, int on)
01149 
01150 {
01151     FENTER("edt_oc192_mdio_set_swap");
01152     edt_oc192_mdio_write(edt_p, 0x2, 
01153         (edt_oc192_mdio_read(edt_p, 0x2) & 0xfb) | ((on)? 0x2 : 0) );
01154     FRETURN("edt_oc192_mdio_set_swap");
01155 }
01156 
01164 void
01165 edt_oc192_mdio_dump(EdtDev *edt_p)
01166 
01167 {       
01168     uint_t i;
01169 
01170     for (i=1; i<=0x1f; i++)
01171         if (i<0x11 || i>0x1d)
01172             printf("%02xH       :  %02xH\n", i, edt_oc192_mdio_read(edt_p, (u_char) i));
01173 }
01174 
01175 
01185 void
01186 edt_oc192_mdio_loopback(EdtDev *edt_p, int on)
01187 
01188 {
01189     FENTER("edt_oc192_mdio_loopback");
01190     edt_oc192_mdio_write(edt_p, 0x1, edt_oc192_mdio_read(edt_p, 0x1) & 0xfd | ((on)? 0:0x2) );
01191     FRETURN("edt_oc192_mdio_loopback");
01192 }
01193 
01203 void
01204 edt_oc192_mdio_set_prbs23(EdtDev *edt_p, int on)
01205 {
01206     /*
01207     * Select prbs23 code
01208     */
01209     FENTER("edt_oc192_mdio_set_prbs23");
01210     edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xe7) | (on) ? 0x10 : 0);
01211     FRETURN("edt_oc192_mdio_set_prbs23");
01212 }
01213 
01223 void
01224 edt_oc192_mdio_set_prbs31(EdtDev *edt_p, int on)
01225 {
01226     /*
01227     * Select prbs23 code
01228     */
01229     FENTER("edt_oc192_mdio_set_prbs31");
01230     edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xe7) | (on) ? 0x11 : 0);
01231     FRETURN("edt_oc192_mdio_set_prbs31");
01232 }
01233 
01241 void
01242 edt_oc192_mdio_standard(EdtDev *edt_p)
01243 
01244 {
01245     FENTER("edt_oc192_mdio_standard");
01246     /*
01247     * Refclk is 155.52, turn on DATA_SWAP
01248     */
01249     edt_oc192_mdio_set_swap(edt_p, 1);
01250 
01251     /*
01252     * Bit 2-0
01253     * Phase offset between high speed recovered data and clock for improved BER
01254     * 000 => + 8.5 ps (default)
01255     * 111 => - 11.0 ps
01256     *
01257     * Bit 7-6
01258     * Post amplifier offset adjust
01259     * 
01260     */
01261     /* 
01262     * post amp equalization adjust
01263     * bit 4-2
01264     * 000               No equalization                         -0.8dB
01265     * 001               0% - 5%                                         1.4dB
01266     * 010               5% - 10%                                        2.4dB
01267     * .......
01268     * 111               30% - 35%                                       7.5dB
01269     */
01270     edt_oc192_mdio_write(edt_p, 0xe, (edt_oc192_mdio_read(edt_p, 0xe) & 0xfb) | 0x18 );
01271 
01272     FRETURN("edt_oc192_mdio_standard");
01273 }
01274 
01286 int
01287 edt_oc192_set_liu(EdtDev *edt_p, int mode)
01288 
01289 {
01290     int rc = 0;
01291     FENTER("edt_oc192_set_liu");
01292 
01293     edt_oc192_reset_liu(edt_p);
01294     edt_oc192_mdio_standard(edt_p);
01295 
01296     switch(mode)
01297     {
01298     case EDT_OC192_LIU_NORMAL:
01299         break;
01300 
01301     case EDT_OC192_LIU_LOOPBACK:
01302         edt_oc192_mdio_loopback(edt_p, 1);
01303         break;
01304 
01305     case EDT_OC192_LIU_REMOTE_LPBK:
01306 
01307         edt_oc192_mdio_write(edt_p, 1, 
01308             (edt_oc192_mdio_read(edt_p, 1) & ~3) | 2);
01309         edt_oc192_mdio_write(edt_p,2,
01310             (edt_oc192_mdio_read(edt_p, 2) & ~0x10));
01311         edt_oc192_mdio_write(edt_p, 0x5, 
01312             edt_oc192_mdio_read(edt_p, 0x5) & ~(0x48));
01313 
01314         break;
01315 
01316     case EDT_OC192_LIU_BIST_TX:
01317         /*
01318         * Refclk is 155.52, turn on DATA_SWAP
01319         */
01320         edt_oc192_mdio_set_swap(edt_p, 1);
01321         /*
01322         * Select prbs23 code
01323         */
01324         edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xf7) | 0x10);
01325         /*
01326         * Transmit built in self test mode
01327         */
01328         edt_oc192_mdio_write(edt_p, 0x5, edt_oc192_mdio_read(edt_p, 0x5) | 0x40);
01329         /*
01330         * Turn on diagnostic loopback
01331         */
01332         edt_oc192_mdio_loopback(edt_p, 1);
01333         break;
01334 
01335     case EDT_OC192_LIU_BIST_TX_EXT:
01336         /*
01337         * Refclk is 155.52, turn on DATA_SWAP
01338         */
01339         edt_oc192_mdio_set_swap(edt_p, 1);
01340         /*
01341         * Select prbs23 code
01342         */
01343         edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xf7) | 0x10);
01344         /*
01345         * Transmit built in self test mode
01346         */
01347         edt_oc192_mdio_write(edt_p, 0x5, edt_oc192_mdio_read(edt_p, 0x5) | 0x40);
01348         /*
01349         * Turn off diagnostic loopback
01350         */
01351         edt_oc192_mdio_loopback(edt_p, 0);
01352         break;
01353 
01354     case EDT_OC192_LIU_BIST_RX:
01355         /*
01356         * Refclk is 155.52, turn on DATA_SWAP
01357         */
01358         edt_oc192_mdio_set_swap(edt_p, 1);
01359         /*
01360         * Select prbs23 code
01361         */
01362         edt_oc192_mdio_write(edt_p, 0x6, (edt_oc192_mdio_read(edt_p, 0x6) & 0xf7) | 0x10);
01363         /*
01364         * Receive built in self test mode
01365         * turn on line loopback
01366         */
01367         edt_oc192_mdio_write(edt_p, 0x5, edt_oc192_mdio_read(edt_p, 0x5) | 0x04);
01368         break;
01369 
01370     default:
01371         rc = -1;
01372     }
01373 
01374     FRETURN_I("edt_oc192_set_liu",rc);
01375     return rc;
01376 }
01377 
01378 
01379 
01391 int
01392 edt_oc192_lock_clocks(EdtDev *edt_p, int timeout)
01393 
01394 {
01395 
01396 
01397     if (edt_p->channel_no == 1 && edt_ocx_lock_local_clock(edt_p, timeout))
01398         return -1;
01399 
01400     if (edt_ocx_lock_channel_clock(edt_p, edt_p->channel_no, timeout))
01401         return -1;
01402 
01403     edt_msg(EDTLIB_MSG_INFO_1,"All System clocks locked          \n");
01404 
01405     return 0;
01406 
01407 }
01408 
01420 int
01421 edt_msdv_lock_clocks(EdtDev *edt_p, int timeout)
01422 
01423 {
01424 
01425 
01426     if (edt_ocx_lock_local_clock(edt_p, timeout) ||
01427         (edt_wait_register_bits_high (edt_p, OCM_CH0_ENABLE, SYS_LOCK,timeout)))
01428     {
01429         edt_msg(EDTLIB_MSG_FATAL,"\rMezzanine System clock not locked");
01430         return -1;
01431 
01432     }
01433 
01434     edt_msg(EDTLIB_MSG_INFO_1,"All System clocks locked          \n");
01435 
01436     return 0;
01437 
01438 }
01439 
01451 char *
01452 edt_oc192_mezz_filename(EdtDev *edt_p, EdtLineRate line_rate)
01453 
01454 {
01455     char *target_bitfile = NULL;
01456 
01457     switch (line_rate) {
01458         case OC3_RATE:      
01459         case OC12_RATE:     
01460         case STM1_RATE:
01461         case STM4_RATE:
01462             if (edt_p->mezz.extended_rev > 1)
01463                 target_bitfile="oc12m2.bit";
01464             else
01465                 target_bitfile="oc12m.bit";
01466 
01467 
01468             break;
01469 
01470         case STM16_RATE:            
01471         case OC48_RATE:     
01472             if (edt_p->mezz.extended_rev > 1)
01473                 target_bitfile="oc48m2.bit";
01474             else
01475                 target_bitfile="oc48m.bit";
01476 
01477             break;
01478         case GIGE_RATE:
01479             if (edt_p->mezz.extended_rev > 1)
01480                 target_bitfile="ethernet_1gbe2.bit";
01481             else
01482                 target_bitfile="ethernet_1gbe.bit";
01483             break;
01484 
01485         case OTU2_RATE:
01486             /* Only supported in raw bits mode (no framing, etc). */
01487         case STM64_RATE:
01488         case OC192_RATE:
01489             if (edt_p->mezz.extended_rev > 1)
01490                 target_bitfile="oc192m2.bit";
01491             else
01492                 target_bitfile="oc192m.bit";
01493             break;
01494         case GIG10E_RATE:
01495             if (edt_p->mezz.extended_rev > 1)
01496                 target_bitfile="ethernet_10gbe2.bit";
01497             else
01498                 target_bitfile="ethernet_10gbe.bit";
01499             break;
01500 
01501     }
01502 
01503     return target_bitfile;
01504 
01505 }
01506 
01507 
01519 char *
01520 edt_net10g_mezz_filename(EdtDev *edt_p, EdtLineRate line_rate)
01521 
01522 {
01523     char *target_bitfile = NULL;
01524 
01525     target_bitfile = "net10g_v5_sdh.bit";
01526 
01527 
01528 
01529     return target_bitfile;
01530 
01531 }
01532 
01533 
01534 
01551 int
01552 edt_oc192_load_default_mezzanine(EdtDev *edt_p, EdtLineRate line_rate,
01553                                  char *mezz_0, char *mezz_1)
01554 
01555 {
01556     int rc = 0;
01557 
01558     char *bitname = edt_oc192_mezz_filename(edt_p, 
01559         (line_rate)?line_rate:OC192_RATE);
01560 
01561     if (mezz_0)
01562         if (mezz_0[0])
01563             bitname = mezz_0;
01564 
01565     rc = edt_bitload(edt_p, NULL, bitname, BITLOAD_FLAGS_MEZZANINE, 0);
01566 
01567     return rc;
01568 }
01569 
01570 
01583 int
01584 edt_oc192_speed_capable(int channel, EdtLineRate line_rate)
01585 
01586 {
01587     int rc = -1;
01588 
01589     switch (line_rate) {
01590         case STM1_RATE:
01591         case STM4_RATE:
01592         case STM16_RATE:            
01593         case OC3_RATE:      
01594         case OC12_RATE:     
01595         case OC48_RATE:     
01596         case GIGE_RATE:
01597             if ((channel & 1) == 0)
01598                 rc = 0;
01599             break;
01600 
01601         case OTU2_RATE:
01602             /* Only supported in raw bits mode (no framing, etc). */
01603         case GIG10E_RATE:
01604         case STM64_RATE:
01605         case OC192_RATE:
01606             if ((channel & 1) == 1)
01607                 rc = 0;
01608             break;
01609 
01610         default:
01611             edt_msg(EDTLIB_MSG_FATAL,"Unknown bit rate %d\n", line_rate);
01612             rc =  -1;
01613 
01614     } 
01615     return rc;
01616 
01617 }
01618 
01619 
01620 
01621 
01622 
01636 int
01637 edt_oc192_has_mezz_bitfile(EdtDev *edt_p, const char *bitfile_name)
01638 
01639 {
01640     int rc;
01641     FENTER_S("edt_oc192_has_correct_bitfile",bitfile_name);
01642 
01643     rc = strcmp(edt_p->bfd.mezz_name0, bitfile_name);
01644 
01645     FRETURN_I("edt_oc192_has_correct_bitfile",rc);
01646 
01647     return rc;
01648 }
01649 
01663 int
01664 edt_net10g_has_mezz_bitfile(EdtDev *edt_p, const char *bitfile_name)
01665 
01666 {
01667     int rc;
01668     FENTER_S("edt_net10g_has_correct_bitfile",bitfile_name);
01669 
01670     rc = strcmp(edt_p->bfd.mezz_name0, bitfile_name);
01671 
01672     FRETURN_I("edt_net10g_has_correct_bitfile",rc);
01673 
01674     return rc;
01675 }
01676 
01691 int
01692 edt_oc192_set_clock_select(EdtDev *edt_p, EdtLineRate line_rate)
01693 
01694 {
01695     int channel = edt_p->channel_no;
01696     int clk_select = 0;
01697 
01698 
01699     FENTER_I("edt_oc192_set_clock_select", line_rate);
01700 
01701     if (channel == 0) 
01702     {
01703         edt_reg_write(edt_p, OC192_CHAN_SELECT, 0x0);
01704 
01705         return edt_ocm_set_clock_select(edt_p, line_rate);
01706 
01707     }
01708     else
01709     {
01710         edt_reg_write(edt_p, OC192_CHAN_SELECT, 0x1);
01711         /* somehow affecting module not ready */
01712         edt_reg_write(edt_p, OC192_ENABLE, PLL_EN);
01713 
01714         edt_msleep(1000);
01715 
01716         /* select clock in register. */
01717         switch (line_rate)
01718         {
01719         case OC192_RATE:
01720         case STM64_RATE:
01721             clk_select = OC192_REFCLK_OC;
01722             break;
01723         case OTU2_RATE:
01724             clk_select = OC192_REFCLK_OTU2;
01725             break;
01726         case GIG10E_RATE:
01727             clk_select = OC192_REFCLK_10GBER;
01728             break;
01729         case GIGE_RATE:
01730         case OC3_RATE:      
01731         case STM1_RATE:
01732         case OC12_RATE:  
01733         case STM4_RATE:
01734         case STM16_RATE:            
01735         case OC48_RATE:
01736         default:
01737             /*Invalid for ch1 oc192*/
01738             clk_select = OC192_REFCLK_OC;
01739             return 1;
01740         }
01741 
01742         edt_reg_write(edt_p, OC192_REF_CLOCK, clk_select);
01743 
01744     }
01745 
01746     FRETURN("edt_oc192_set_clock_select");
01747 
01748     return 0;
01749 
01750 }
01751 
01752 void edt_oc192_set_merged_mezz(EdtDev *edt_p, int state)
01753 
01754 {
01755     if (state)
01756     {
01757         edt_reg_or(edt_p, OC192_DUAL_CHANNEL_MODE, 4);
01758     }
01759     else
01760     {
01761         int val = edt_reg_read(edt_p, OC192_DUAL_CHANNEL_MODE);
01762 
01763         edt_reg_write(edt_p, OC192_DUAL_CHANNEL_MODE, val);
01764     }
01765 }
01766 
01767 
01768 
01779 int
01780 edt_oc192_clear_demux(EdtDev *edt_p)
01781 
01782 {
01783     int i;
01784 
01785     FENTER("edt_oc192_clear_demux");
01786 
01787     /* make sure demux is turned off */
01788     edt_reg_write(edt_p, OC192_DEMUX_BITMASK, 0);
01789     for (i=0x80;i<0x8c;i++)
01790         edt_reg_write(edt_p, OC192_DEMUX_MASK_ADDR, i);
01791 
01792 
01793     FRETURN("edt_oc192_clear_demux");
01794 
01795     return 0;
01796 
01797 }
01798 
01808 void
01809 edt_oc192_set_framer(EdtDev *edt_p, int flags)
01810 
01811 {
01812 
01813     int rx_ctrl;
01814 
01815     FENTER_I("edt_oc192_set_framer", flags);
01816 
01817     rx_ctrl = 0;
01818     if (flags & EDT_OCX_FRAMED)
01819     {
01820         rx_ctrl |= OC192_FRAME_EN;
01821         if ((flags & EDT_OCX_DESCRAMBLE) == 0)
01822             rx_ctrl |= OC192_DISABLE_SCRAM;
01823     }
01824 
01825     edt_reg_write(edt_p, OC192_FRAMING, rx_ctrl);
01826 
01827     FRETURN("edt_oc192_set_framer");
01828 
01829 }
01830 
01849 int
01850 edt_oc192_channel_lock_frontend(EdtDev *edt_p, EdtOCConfig *cfg)
01851 
01852 {
01853     int rc;
01854     int rx_filter;
01855     int liu_check;
01856 
01857     /* AMCC received clock not locked */
01858 
01859     if ((edt_p->channel_no & 1) == 0)
01860         return edt_ocm_channel_lock_frontend(edt_p, cfg);
01861 
01862     if (edt_p->channel_no == 3)
01863         liu_check = 2;
01864     else
01865         liu_check = 1;
01866 
01867     if (cfg->flags & EDT_OCX_PRBS_EN)
01868     {
01869         // no need on loopback prbs
01870     }
01871     else
01872     {
01873         if ((rc = edt_wait_register_bits_high(edt_p, OC192_LIU_STATUS, liu_check, cfg->timeout)))
01874         {
01875             edt_msg(EDTLIB_MSG_FATAL,"AMCC receiver won't lock\n");
01876             return -1;
01877         }
01878         else
01879             edt_msg(EDTLIB_MSG_INFO_1,"AMCC receiver PLL is locked\n");
01880 
01881         /* added 2/13/2008 jsc */
01882 
01883         rx_filter = (u_char) edt_reg_read(edt_p, OC192_RCV_FILTER);
01884         rx_filter &= ~OVERHEAD_ONLY; 
01885         if (cfg->flags & EDT_OCX_OVHD_ONLY) 
01886         {
01887             if (cfg->flags & EDT_OCX_FRAMED)
01888                 rx_filter |= OVERHEAD_ONLY; 
01889             else
01890                 edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
01891         }
01892         edt_reg_write(edt_p, OC192_RCV_FILTER, rx_filter); 
01893 
01894     }
01895 
01896     edt_reg_write(edt_p, OC192_ENABLE, 0);
01897     edt_reg_write(edt_p, OC192_ENABLE, 0x4);
01898     edt_reg_write(edt_p, OC192_ENABLE, 0xc);
01899     edt_reg_write(edt_p, OC192_ENABLE, 0x1c);
01900     edt_msleep(100);
01901     edt_reg_write(edt_p, OC192_ENABLE, 0x1e);
01902     edt_msleep(50);
01903 
01904     if (edt_p->channel_no == 1)
01905     {
01906     /* Received DCM not locked */
01907     if ((rc = edt_wait_register_bits_high(edt_p, OC192_ENABLE, 0xf0, cfg->receive_dcm_timeout)))
01908     {
01909         edt_msg(EDTLIB_MSG_FATAL,"Receive DCM won't lock\n");
01910         return -1;
01911 
01912     }
01913     else
01914         edt_msg(EDTLIB_MSG_INFO_1,"Receive DCM Locked\n");
01915 
01916     }
01917 
01918 
01919     return 0;
01920 
01921 }
01922 
01941 int
01942 edt_net10g_channel_lock_frontend(EdtDev *edt_p, EdtOCConfig *cfg)
01943 
01944 {
01945     int rc;
01946     int rx_filter;
01947 
01948     /* AMCC received clock not locked */
01949 
01950     if ((rc = edt_wait_register_bits_high(edt_p, OC192_LIU_STATUS, 0x1, cfg->timeout)))
01951     {
01952         edt_msg(EDTLIB_MSG_FATAL,"AMCC receiver won't lock\n");
01953         return -1;
01954     }
01955     else
01956         edt_msg(EDTLIB_MSG_INFO_1,"AMCC receiver PLL is locked\n");
01957 
01958     /* added 2/13/2008 jsc */
01959 
01960     rx_filter = (u_char) edt_reg_read(edt_p, OC192_RCV_FILTER);
01961     rx_filter &= ~OVERHEAD_ONLY; 
01962     if (cfg->flags & EDT_OCX_OVHD_ONLY) 
01963     {
01964         if (cfg->flags & EDT_OCX_FRAMED)
01965             rx_filter |= OVERHEAD_ONLY; 
01966         else
01967             edt_msg(EDT_MSG_WARNING,"Overhead filter does not work in raw data mode\n");
01968     }
01969     edt_reg_write(edt_p, OC192_RCV_FILTER, rx_filter); 
01970 
01971     edt_reg_write(edt_p, OC192_ENABLE, 0);
01972     edt_reg_write(edt_p, OC192_ENABLE, 0x2);
01973     edt_reg_write(edt_p, OC192_ENABLE, 0x6);
01974     edt_reg_write(edt_p, OC192_ENABLE, 0xe);
01975     edt_reg_write(edt_p, OC192_ENABLE, 0x1e);
01976     edt_msleep(100);
01977 
01978     /* Received DCM not locked */
01979     if ((rc = edt_wait_register_bits_high(edt_p, OC192_ENABLE, 0xb0, cfg->timeout)))
01980     {
01981         edt_msg(EDTLIB_MSG_FATAL,"Receive DCM won't lock\n");
01982         return -1;
01983 
01984     }
01985     else
01986         edt_msg(EDTLIB_MSG_INFO_1,"Receive DCM Locked\n");
01987 
01988 
01989 
01990     return 0;
01991 
01992 }
01993 
01994 int
01995 edt_oc192_laser_on(EdtDev *edt_p, EdtOCConfig *cfg)
01996 
01997 {
01998 
01999     EdtXfpSfpRealValue realval;
02000 
02001     if (!cfg->xfp_p)
02002         cfg->xfp_p = edt_open_xfp_sfp_device(edt_p);
02003 
02004     if (!cfg->xfp_p)
02005         return 1;
02006 
02007     edt_xfp_sfp_read_current_values(edt_p, cfg->xfp_p);
02008 
02009     edt_xfp_sfp_real_value(edt_p, cfg->xfp_p, EDT_TX_POWER_MW, &realval);
02010 
02011     return (realval.value > 0);    
02012 }
02013 
02014 int
02015 edt_oc192_enable_laser(EdtDev *edt_p, EdtOCConfig *cfg)
02016 
02017 {
02018 
02019     double t1, t2;
02020     int first = 1;
02021  
02022     edt_reg_write(edt_p, OC192_XCVR_CTL_STAT, 5);
02023 
02024     t1 = edt_timestamp();
02025 
02026     while (!edt_oc192_laser_on(edt_p, cfg))
02027     {
02028 
02029         if (first)
02030         {
02031             edt_msg(EDTLIB_MSG_WARNING,"Waiting for Laser Warmup... This can take up to 30 seconds\n");
02032             first = 0;
02033         }
02034 
02035         edt_msleep(500);
02036 
02037     }
02038 
02039     if (!first)
02040     {
02041         edt_msg(EDTLIB_MSG_WARNING, "Enabled after %f seconds\n", edt_timestamp() - t1);
02042     }
02043 
02044     return 0;
02045 }
02046 
02047 
02064 int
02065 edt_oc192_channel_setup(EdtDev *edt_p, 
02066                         EdtOCConfig *cfg)
02067 
02068 {
02069     int rc;
02070 
02071     edt_reg_write(edt_p, OC192_CHAN_SELECT, 0x1);
02072 
02073     /* turn off output as prbs (must be turned off for tagging) */
02074 
02075     edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0);
02076     /* power up transceiver */
02077 
02078     edt_reg_write(edt_p, OC192_XCVR_CTL_STAT, 0x4);
02079 
02080     if (!(cfg->flags & EDT_OCX_PRBS_EN) && (edt_p->channel_no == 1))
02081     {
02082         if (rc = edt_wait_register_bits_low(edt_p, OC192_XCVR_CTL_STAT, 0x50, cfg->timeout))
02083         {
02084             edt_msg(EDTLIB_MSG_FATAL,"module absent/loss of signal/(module not ready)\n");
02085             return -1;
02086         }
02087     }
02088 
02089     if(cfg->flags & EDT_OCX_LOOPBACK) {
02090         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_LOOPBACK);
02091         edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0x19);
02092     } else if (cfg->flags & EDT_OCX_REMOTE_LPBK)
02093     {
02094           edt_oc192_set_liu(edt_p, EDT_OC192_LIU_REMOTE_LPBK);
02095           edt_oc192_enable_laser(edt_p, cfg);
02096     }
02097     else
02098     {
02099 
02100         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_NORMAL);
02101     }
02102 
02103     /* set framer */
02104 
02105     if (edt_p->channel_no == 1)
02106     {
02107         edt_oc192_set_framer(edt_p, cfg->flags);
02108 
02109         if (cfg->flags & EDT_OCX_TAGGED_DATA)
02110             edt_oc192_set_tagging(edt_p,1,cfg->tagid);
02111     }
02112     else
02113     {
02114         /* turn on memory */
02115         edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0x20);
02116         /* power up transceiver */
02117 
02118         edt_oc192_enable_laser(edt_p, cfg);
02119 
02120     }
02121 
02122     return 0;
02123 }
02124 
02141 int
02142 edt_net10g_channel_setup(EdtDev *edt_p, 
02143                          EdtOCConfig *cfg)
02144 
02145 {
02146     int rc;
02147 
02148     edt_reg_write(edt_p, OC192_CHAN_SELECT, 0x1);
02149 
02150     /* turn off output as prbs (must be turned off for tagging) */
02151 
02152     edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0);
02153     /* power up transceiver */
02154 
02155     edt_reg_write(edt_p, OC192_XCVR_CTL_STAT, 0x4);
02156 
02157     if (rc = edt_wait_register_bits_low(edt_p, OC192_XCVR_CTL_STAT, 0x50, cfg->timeout))
02158     {
02159         edt_msg(EDTLIB_MSG_FATAL,"module absent/loss of signal/(module not ready)\n");
02160         return -1;
02161     }
02162 
02163     if(cfg->flags & EDT_OCX_LOOPBACK) {
02164         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_LOOPBACK);
02165         edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0x19);
02166     } else {
02167         edt_oc192_set_liu(edt_p, EDT_OC192_LIU_NORMAL);
02168     }
02169 
02170     /* set framer */
02171 
02172     edt_oc192_set_framer(edt_p, cfg->flags);
02173 
02174     if (cfg->flags & EDT_OCX_TAGGED_DATA)
02175         edt_oc192_set_tagging(edt_p,1,cfg->tagid);
02176 
02177     return 0;
02178 }
02179 
02192 int
02193 edt_oc192_wait_for_frame(EdtDev *edt_p, int timeout)
02194 
02195 {
02196     int rc = 0;
02197 
02198     FENTER("edt_oc192_wait_for_frame");
02199 
02200     edt_msg(EDTLIB_MSG_INFO_1,"Waiting for frame CH%d", edt_p->channel_no);
02201 
02202     if (rc = edt_wait_register_bits_high(edt_p, OC192_FRAMING, 
02203         OC192_FRAME_LOCK , timeout))
02204     { 
02205         edt_msg(EDTLIB_MSG_FATAL," - Framing timed out\n");
02206         rc = -1;
02207     }
02208     else
02209         edt_msg(EDTLIB_MSG_INFO_1," framed\n");
02210 
02211     FRETURN_I("edt_oc192_wait_for_frame", rc);
02212 
02213     return rc;
02214 
02215 }
02216 
02232 int
02233 edt_oc192_set_tagging(EdtDev *edt_p, int state, int tagid)
02234 
02235 {
02236     u_char mask = 0;
02237 
02238     if (state)
02239     {
02240         /* All boards are set up to acquire only selected 
02241         tag id data, and to transmit on to the 
02242         next board */
02243 
02244         mask = OC192_TAGS_ONLY | OC192_TAGS_XMIT |
02245             (tagid & OC192_TAG_MASK);
02246 
02247         /* Only tag 0 board actually generates tags */
02248 
02249         if (tagid == 0)
02250         {
02251             mask |= OC192_TAG_ON;
02252 
02253         }
02254 
02255         /* turn off output as prbs (must be turned off for tagging) */
02256 
02257         edt_reg_write(edt_p, OC192_OUTPUT_DATA_SEL, 0);
02258         /* power up transceiver */
02259 
02260         edt_reg_write(edt_p, OC192_TAG_CTRL, mask);
02261 
02262         edt_reg_write(edt_p, OC192_XCVR_CTL_STAT, 0x5);
02263         /* turn on laser */
02264 
02265 
02266     }
02267     else
02268         edt_reg_write(edt_p, OC192_TAG_CTRL, 0);
02269 
02270     return 0;
02271 
02272 }
02273 
02274 int
02275 edt_oc192_get_overrun(EdtDev *edt_p)
02276 
02277 {
02278     if (edt_p && edt_p->channel_no == 1)
02279     {
02280         u_int i = edt_intfc_read(edt_p, 0x94) & 2;
02281         return (i != 0);
02282     }
02283     else
02284         return FALSE;
02285 }
02286 
02287 int
02288 edt_oc192_get_underrun(EdtDev *edt_p)
02289 
02290 {
02291     if (edt_p && edt_p->channel_no == 1)
02292     {
02293         u_int i = edt_intfc_read(edt_p, 0x94) & 8;
02294         return (i != 0);
02295     }
02296     else
02297         return FALSE;
02298 }
02299 
02300 /******************************************************
02301 *
02302 * edt_ocx_functions - apply to euther OCM or OC 192 mezzanine boards
02303 *
02304 ******************************************************/
02305 
02306 
02307 /***************************************
02308 *
02309 ***************************************/
02310 
02320 char *
02321 edt_ocx_default_bitfile(int mezz_id)
02322 
02323 {
02324     char *workfile = NULL;
02325 
02326     switch (mezz_id)
02327     {
02328     case MEZZ_OCM:
02329         workfile = "ocm.bit";
02330         break;
02331     case MEZZ_OC192:
02332         workfile = "oc192.bit";
02333         break;
02334     case MEZZ_MSDV:
02335         workfile = "msdv.bit";
02336         break;
02337     case MEZZ_NET10G:
02338         workfile = "net10g.bit";
02339         break;
02340 
02341     }
02342 
02343     return workfile;
02344 
02345 }
02346 
02362 int
02363 edt_ocx_check_interface(EdtDev *edt_p, char *target_file, int force_load)
02364 
02365 {
02366     int rc = 0;
02367     char *workfile = target_file;
02368 
02369     FENTER_S("edt_ocx_check_interface",target_file);
02370 
02371 
02372     if (workfile == NULL || (workfile && (strlen(workfile) == 0)))
02373     {
02374         workfile = edt_ocx_default_bitfile(edt_p->mezz.id);
02375 
02376         if (workfile == NULL)
02377         {
02378             edt_msg(EDTLIB_MSG_FATAL, "Unable to select interface bitfile for mezzanine %x\n",
02379                 edt_p->mezz.id);
02380             return -1;
02381         }
02382     }
02383 
02384     if (strcmp(edt_p->bfd.bitfile_name, workfile))
02385     {
02386 
02387         if (force_load)
02388         {
02389             edt_msg(EDTLIB_MSG_WARNING, "Loading interface file %s\n",
02390                 workfile);
02391 
02392             rc = (edt_bitload(edt_p, NULL, workfile, 0,0) != 0);        
02393 
02394             /* have to get the board description again */
02395             if (rc == 0)
02396                 edt_get_board_description(edt_p, FALSE);
02397 
02398         }
02399         if (rc != 0)
02400         {
02401             edt_msg(EDTLIB_MSG_FATAL, "Unable to load bitfile %s\n", workfile);
02402         }
02403     }
02404 
02405     /* ok */
02406     FRETURN_I("edt_ocx_check_interface",rc);
02407 
02408     return rc;
02409 
02410 }
02411 
02412 
02413 
02414 
02427 int
02428 edt_ocx_lock_clocks(EdtDev *edt_p, int timeout)
02429 
02430 {
02431     switch(edt_p->mezz.id)
02432     {
02433     case MEZZ_OCM:
02434         return edt_ocm_lock_clocks(edt_p, timeout);
02435     case MEZZ_NET10G:
02436     case MEZZ_OC192:
02437         return edt_oc192_lock_clocks(edt_p, timeout);
02438     case MEZZ_MSDV:
02439         return edt_msdv_lock_clocks(edt_p, timeout);
02440     default:
02441         edt_msg(EDTLIB_MSG_FATAL, "Mezz ID must be OCM or OC192 in edt_ocx_lock_clocks\n");
02442         return -1;
02443     }
02444 
02445 }
02446 
02447 
02448 
02468 int
02469 edt_ocx_load_default_mezzanine(EdtDev *edt_p, 
02470                                EdtLineRate line_rate,
02471                                char *mezz_0,
02472                                char *mezz_1)
02473 
02474 {
02475     switch(edt_p->mezz.id)
02476     {
02477     case MEZZ_OCM:
02478         return edt_ocm_load_default_mezzanine(edt_p, 
02479             line_rate, mezz_0, mezz_1);
02480     case MEZZ_OC192:
02481         return edt_oc192_load_default_mezzanine(edt_p, 
02482             line_rate, mezz_0, mezz_1);
02483     case MEZZ_MSDV:
02484         return edt_msdv_load_default_mezzanine(edt_p, mezz_0);
02485     case MEZZ_NET10G:
02486         return edt_net10g_load_default_mezzanine(edt_p, mezz_0, mezz_1);
02487     default:
02488         edt_msg(EDTLIB_MSG_FATAL, "Mezz ID must be OCM, OC192, MSDV, or NET10G in edt_ocx_load_fault_mezzanine\n");
02489         return -1;
02490     }
02491 }
02492 
02493 
02510 int
02511 edt_ocx_base_init(EdtDev *edt_p, 
02512                   EdtOCConfig *cfg)
02513 
02514 {
02515     int rc = 0;
02516     int force_load = !(cfg->flags & EDT_OCX_SKIP_LOAD);
02517 
02518 
02519     FENTER("edt_ocx_init");
02520 
02521 
02522     /* identify mezz board */
02523     if ((rc = edt_get_board_description(edt_p, force_load)) != 0)
02524     {
02525         edt_msg(EDTLIB_MSG_FATAL, "Unable to get board description\n");
02526         return rc;
02527     }
02528 
02529     if (edt_p->mezz.id != MEZZ_OCM && edt_p->mezz.id != MEZZ_OC192 && edt_p->mezz.id != MEZZ_MSDV &&
02530         edt_p->mezz.id != MEZZ_NET10G)
02531     {
02532 
02533         edt_msg(EDTLIB_MSG_FATAL, "Mezzanine ID = %d, OCM or OC192 or MSDV expected\n",
02534             edt_p->mezz.id);
02535 
02536         edt_print_board_description(edt_p); 
02537 
02538         return -1;
02539     }
02540 
02541 
02542     /* load base bitfile if necessary */
02543     /* check bitfile */
02544 
02545     if ((rc = edt_ocx_check_interface(edt_p, cfg->intfc, !(cfg->flags & EDT_OCX_SKIP_LOAD))) != 0)
02546     {
02547         FRETURN_I("edt_ocx_check_bitfiles",rc);
02548         return rc;
02549     }
02550 
02551     /* load default mezzanine if necessary */
02552     if (edt_p->bfd.mezz_name0[0] == 0)
02553     {
02554         edt_ocx_load_default_mezzanine(edt_p, 
02555             cfg->line_rate,
02556             cfg->mezz_0,
02557             cfg->mezz_1);
02558     }
02559 
02560     /* Reset channel enables and 100 MHz ref. clock */
02561     edt_msg(EDTLIB_MSG_INFO_1,"Full init\n");
02562 
02563     edt_reg_write(edt_p, PCD_CMD, 0); /* reset user xilinx */
02564     edt_reg_write(edt_p, PCD_CMD, 0); /* reset user xilinx */
02565     edt_reg_write(edt_p, PCD_CMD, 8);
02566     edt_reg_write(edt_p, SSD16_CHENL, 0); /* disable all channels */
02567     edt_reg_write(edt_p, SSD16_LSBL, 0); /* reset lsb first which means msb is first in time */
02568 
02569     /* reset sysclk on both mezzanine xilinx */
02570     /* note some redundancy for OC192, since only one channel is active at a time */
02571 
02572     edt_reg_write(edt_p, OCM_CH0_ENABLE , 0x0); /* reset all the OCM enables */
02573     edt_reg_write(edt_p, OCM_CH0_ENABLE , RAM_EN | SYS_EN); /* reset all the OCM enables */
02574     edt_reg_write(edt_p, OCM_CH0_ENABLE + OFFSET_CH1_BASE, 0x0); /* reset all the OCM enables */
02575     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*/
02576     edt_flush_fifo(edt_p) ;         /* Flush the input fifo */
02577 
02578     if (cfg->flags & EDT_OCX_SWAP)
02579         edt_reg_write(edt_p, PCD_CONFIG, PCD_BYTESWAP | PCD_SHORTSWAP); 
02580     else
02581         edt_reg_write(edt_p, PCD_CONFIG, 0); 
02582 
02583     /* synch clocks */
02584 
02585     /* get plls working */
02586     rc = edt_ocx_lock_clocks(edt_p, cfg->timeout);
02587 
02588     if (ID_IS_LX(edt_p->devid) && edt_p->mezz.id == MEZZ_OC192 || 
02589         edt_p->mezz.id == MEZZ_NET10G)
02590     {
02591         if (edt_p->channel_no < 2)
02592             edt_reg_write(edt_p, EDT_PCIE_CFG, 0x50);
02593         else
02594             edt_reg_write(edt_p, EDT_PCIE_CFG, 0x54);
02595     }
02596 
02597     FRETURN("edt_ocx_base_init");
02598 
02599     return rc;
02600 
02601 }
02602 
02603 
02604 
02617 int
02618 edt_ocx_speed_capable(EdtDev *edt_p, EdtLineRate line_rate)
02619 
02620 {
02621     int rc;
02622 
02623     FENTER("edt_ocx_speed_capable");
02624 
02625     if (edt_p->mezz.id == MEZZ_OC192 || edt_p->mezz.id == MEZZ_NET10G)
02626 
02627         rc = edt_oc192_speed_capable(edt_p->channel_no, line_rate);
02628 
02629     else if (edt_p->mezz.id == MEZZ_OCM)
02630 
02631         rc = edt_ocm_speed_capable(edt_p->channel_no, line_rate);
02632 
02633     else 
02634         rc = -1;
02635 
02636     FRETURN_I("edt_ocx_speed_capable",rc);
02637 
02638     return rc;
02639 
02640 }
02641 
02642 
02643 
02656 int
02657 edt_ocx_has_mezz_bitfile(EdtDev *edt_p, const char *bitfile_name)
02658 
02659 {
02660     int rc = -1;
02661 
02662     FENTER_S("edt_ocx_has_correct_bitfile",bitfile_name);
02663 
02664     if (edt_p->mezz.id == MEZZ_OC192)
02665     {
02666         rc = edt_oc192_has_mezz_bitfile(edt_p, bitfile_name);
02667     }
02668     else if (edt_p->mezz.id == MEZZ_OCM)
02669     {
02670         rc = edt_ocm_has_mezz_bitfile(edt_p, bitfile_name);
02671     }
02672     else if (edt_p->mezz.id == MEZZ_NET10G)
02673     {
02674         rc = edt_net10g_has_mezz_bitfile(edt_p, bitfile_name);
02675     }
02676     else
02677         rc = -1;
02678 
02679 
02680     FRETURN_I("edt_ocx_has_correct_bitfile",rc);
02681 
02682     return rc;
02683 
02684 }
02685 
02686 
02697 const char *
02698 edt_ocx_mezz_filename(EdtDev *edt_p, EdtLineRate line_rate)
02699 
02700 {
02701     switch(edt_p->mezz.id)
02702     {
02703     case MEZZ_OCM:
02704         return edt_ocm_mezz_filename(edt_p, line_rate);
02705     case MEZZ_OC192:
02706         return edt_oc192_mezz_filename(edt_p, line_rate);
02707     case MEZZ_NET10G:
02708         return edt_net10g_mezz_filename(edt_p, line_rate);
02709     }
02710 
02711     return NULL;
02712 
02713 }
02714 
02728 int
02729 edt_ocx_check_mezz_bitfile(EdtDev *edt_p,
02730                            EdtOCConfig *cfg)
02731 
02732 {  
02733     int channel = edt_p->channel_no & 1;
02734     const char *target_bitfile = NULL;
02735     int rc = 0;
02736     int force_load = (cfg->flags & EDT_OCX_SKIP_LOAD) == 0;
02737 
02738     FENTER("edt_ocx_check_mezz_bitfile");
02739 
02740     if (edt_p->mezz.id == MEZZ_OC192 && cfg->mezz_0[0])
02741         target_bitfile = cfg->mezz_0;
02742     else if (channel == 0 && cfg->mezz_0[0])
02743         target_bitfile = cfg->mezz_0;
02744     else if (cfg->mezz_1[0])
02745         target_bitfile = cfg->mezz_1;
02746 
02747 
02748     if (target_bitfile == NULL)
02749         target_bitfile = edt_ocx_mezz_filename(edt_p,  cfg->line_rate);
02750 
02751     if (target_bitfile == NULL)
02752     {
02753         edt_msg(EDTLIB_MSG_FATAL,"Invalid bit rate %d\n", cfg->line_rate);
02754         return -1;
02755     }
02756 
02757     if (edt_ocx_has_mezz_bitfile(edt_p, target_bitfile))
02758     {
02759         if (!force_load)
02760         {
02761             edt_msg(EDTLIB_MSG_FATAL,
02762                 "Wrong mezzanine bitfile %s for bit rate %d. \nUnset flag EDT_OCX_SKIP_LOAD to load\n",
02763                 target_bitfile, cfg->line_rate);
02764             return -1;
02765         }
02766 
02767         edt_msg(EDTLIB_MSG_WARNING,"wrong mezzanine bitfile for line_rate - reloading with %s \n",
02768             target_bitfile);
02769 
02770         if (edt_p->mezz.id == MEZZ_OCM)
02771         {
02772             int flags = BITLOAD_FLAGS_OVR | BITLOAD_FLAGS_OCM;
02773             if (channel == 1)
02774                 flags |= BITLOAD_FLAGS_CH1;
02775 
02776             rc = edt_bitload(edt_p, NULL, target_bitfile, flags, 0);
02777         }
02778         else
02779         {
02780             edt_msg(EDTLIB_MSG_INFO_1,"Going to edt_bitload with %s\n", target_bitfile);
02781             rc = edt_bitload(edt_p, NULL, target_bitfile, BITLOAD_FLAGS_MEZZANINE, 0);
02782         }
02783     }
02784 
02785     FRETURN_I("edt_ocx_check_mezz_bitfile", rc);
02786 
02787     return rc;
02788 }
02789 
02790 
02791 
02803 int
02804 edt_ocx_set_clock_select(EdtDev *edt_p, EdtLineRate line_rate)
02805 
02806 {
02807     switch(edt_p->mezz.id)
02808     {
02809     case MEZZ_OCM:
02810         return edt_ocm_set_clock_select(edt_p, line_rate);
02811     case MEZZ_OC192:
02812         return edt_oc192_set_clock_select(edt_p, line_rate);
02813 
02814     }
02815 
02816     return -1;
02817 }
02818 
02833 void
02834 edt_ocx_set_channel_enable(EdtDev *edt_p, int channel, int state)
02835 
02836 {
02837     int channel_mask = (1 << channel);
02838     edt_reg_set_bitmask(edt_p, SSD16_CHEN, channel_mask, state);
02839 
02840 }
02841 
02842 void
02843 edt_ocx_set_channel_direction(EdtDev *edt_p, int channel, int do_write)
02844 
02845 {
02846     int channel_mask = (((do_write)?1:0) << channel);
02847     edt_reg_set_bitmask(edt_p, SSD16_CHDIR, channel_mask, do_write);
02848 
02849 }
02850 
02851 
02852 
02867 void
02868 edt_ocx_set_lsbfirst(EdtDev *edt_p, int channel, int state)
02869 
02870 {
02871     int channel_mask = (1 << channel);
02872     if (state)
02873         edt_reg_or(edt_p, SSD16_LSB, channel_mask);
02874     else
02875         edt_reg_and(edt_p, SSD16_LSB, ~channel_mask);
02876 
02877 }
02878 
02892 int
02893 edt_ocx_channel_signal_detect(EdtDev *edt_p)
02894 
02895 {
02896     u_int base_offset = 0;
02897 
02898     if (edt_p->channel_no == 1)
02899     {
02900         base_offset = OFFSET_CH1_BASE;
02901     }
02902 
02903     if (edt_p->mezz.id == MEZZ_OC192)
02904     {
02905         if (edt_p->channel_no == 1)
02906             return ((edt_reg_read(edt_p, OC192_XCVR_CTL_STAT) & LOS) != 0);
02907         else
02908             return 1;
02909         /* check signal detect */
02910     }
02911     else
02912         return ((edt_reg_read(edt_p, OCM_CH0_STATUS + base_offset) & SIG_DET) != 0);
02913 
02914 }
02915 
02916 
02929 void
02930 edt_ocx_reset_sys_en(EdtDev *edt_p, int channel)
02931 
02932 {
02933     int oc_channel = channel & 1;
02934     int chen = OCM_CH0_ENABLE + (oc_channel)?OFFSET_CH1_BASE:0;
02935 
02936     edt_reg_write(edt_p, chen, 0x0); /* reset the OCM enables */
02937     edt_reg_write(edt_p, chen, SYS_EN); /* reset the OCM enables */
02938 
02939 }
02940 
02955 int
02956 edt_ocx_channel_set_rate(EdtDev *edt_p, EdtOCConfig *cfg)
02957 
02958 
02959 {
02960     int channel = edt_p->channel_no & 1;
02961     int rc = 0;
02962 
02963     FENTER("edt_ocx_channel_set_rate");
02964 
02965     /* make sure board is identified */
02966     if (edt_p->mezz.id == 0xff)
02967     {
02968         if (edt_get_board_description(edt_p, FALSE) != 0)
02969         {
02970             edt_msg(EDTLIB_MSG_FATAL, "Unable to get board description in edt_ocx_channel_set_rate\n");
02971             return -1;
02972         }
02973 
02974     }
02975 
02976     /* check rate */
02977     if (edt_ocx_speed_capable(edt_p, cfg->line_rate))
02978     {
02979         edt_msg(EDTLIB_MSG_FATAL,"This channel %d not capable of this rate %d\n",
02980             channel, cfg->line_rate);
02981         return -1;
02982     }
02983 
02984     /* check bitfile */
02985 
02986     if ((rc = edt_ocx_check_mezz_bitfile(edt_p, cfg)) != 0)
02987     {
02988         edt_msg(EDTLIB_MSG_FATAL,"Can't load desired bitfile\n");
02989         return -1;
02990 
02991     }
02992 
02993     /* load new mezz bitfile if necessary */
02994 
02995     edt_msg(EDTLIB_MSG_INFO_1,"Setting channel %d to rate %d\n", edt_p->channel_no, cfg->line_rate);
02996 
02997     /* disable selected channel */
02998     edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, 0);
02999 
03000     /* reset lsb first which means msb is first in time */
03001 
03002     edt_ocx_set_lsbfirst(edt_p, edt_p->channel_no, cfg->flags & EDT_OCX_LSB_FIRST);
03003 
03004     edt_flush_channel(edt_p, edt_p->channel_no);
03005 
03006     edt_ocx_reset_sys_en(edt_p, edt_p->channel_no);
03007 
03008     /* If new bitfile, resynch SYS_LOCK for this channel */
03009     edt_ocx_lock_channel_clock(edt_p, channel, cfg->timeout);
03010 
03011     /* select the correct clock source */
03012 
03013     edt_ocx_set_clock_select(edt_p, cfg->line_rate);
03014 
03015     edt_ocx_enable_framing_errors(edt_p, FALSE);
03016 
03017     FRETURN("edt_ocx_channel_set_rate");
03018 
03019     return rc;
03020 }
03021 
03033 int
03034 edt_ocx_channel_lock_frontend(EdtDev *edt_p,
03035                               EdtOCConfig *cfg)
03036 
03037 
03038 {
03039     if (edt_p->mezz.id == 0xff)
03040     {
03041         if (edt_get_board_description(edt_p, FALSE) != 0)
03042         {
03043             edt_msg(EDTLIB_MSG_FATAL, "Unable to get board description in edt_ocx_channel_lock_frontend\n");
03044             return -1;
03045         }
03046 
03047     }
03048 
03049     if (edt_p->channel_no & 1)
03050     {
03051         if (edt_p->mezz.id == MEZZ_NET10G)
03052             return edt_net10g_channel_lock_frontend(edt_p, cfg);
03053         else if (edt_p->mezz.id == MEZZ_OC192)
03054             return edt_oc192_channel_lock_frontend(edt_p, cfg);
03055     }
03056 
03057     return edt_ocm_channel_lock_frontend(edt_p, cfg);
03058 
03059 }
03060 
03061 
03073 int
03074 edt_ocx_channel_setup(EdtDev *edt_p,
03075                       EdtOCConfig *cfg)
03076 
03077 
03078 {
03079     /* make sure board is identified */
03080     if (edt_p->mezz.id == 0xff)
03081     {
03082         if (edt_get_board_description(edt_p, FALSE) != 0)
03083         {
03084             edt_msg(EDTLIB_MSG_FATAL, "Unable to get board description in edt_ocx_channel_setup\n");
03085             return -1;
03086         }
03087 
03088     }
03089     if (edt_p->channel_no & 1)
03090         if (edt_p->mezz.id == MEZZ_OC192 || edt_p->mezz.id == MEZZ_NET10G)
03091             return edt_oc192_channel_setup(edt_p, cfg);
03092 
03093     return edt_ocm_channel_setup(edt_p, cfg);
03094 
03095 }
03096 
03119 int
03120 edt_ocx_configure(EdtDev *edt_p, 
03121                   EdtOCConfig *cfg)
03122 
03123 {       
03124     int rc = 0;
03125     /*
03126     * configure the OCM board - assume ocmload has been run
03127     */
03128     /* check correct version of bitfiles loaded */
03129 
03130     FENTER("edt_ocx_configure");
03131 
03132     edt_msg(EDTLIB_MSG_INFO_1,"configure for speed %d on channel %d\n", 
03133         cfg->line_rate, edt_p->channel_no);
03134 
03135     /* load baseboard if requested */
03136 
03137     if (cfg->flags & EDT_OCX_FULL_INIT)
03138     {
03139         if (edt_ocx_base_init(edt_p, cfg) != 0)
03140         {
03141             edt_msg(EDTLIB_MSG_FATAL, "Unable to execute base init for unit %d at rate %d\n",
03142                 edt_p->unit_no, cfg->line_rate);
03143             rc = -1;
03144         }
03145     }
03146     else
03147     {
03148         edt_get_board_description(edt_p, FALSE);
03149     }
03150 
03151     if (rc == 0)
03152     {
03153         /* set rate */
03154 
03155         if (edt_ocx_channel_set_rate(edt_p, cfg) != 0)
03156         {
03157             edt_msg(EDTLIB_MSG_FATAL, "Unable to set rate for unit %d channel %d at rate %d\n",
03158                 edt_p->unit_no, edt_p->channel_no, cfg->line_rate);
03159             rc = -1;
03160         }
03161         /* OK, configure channel parameters */
03162         else if (edt_ocx_channel_setup(edt_p, cfg) != 0)
03163         {
03164             edt_msg(EDTLIB_MSG_FATAL, "Unable to set channel parameters unit %d channel %d at rate %d\n",
03165                 edt_p->unit_no, edt_p->channel_no, cfg->line_rate);
03166             rc = -1;
03167 
03168         }
03169         else if (edt_ocx_channel_lock_frontend(edt_p, cfg) != 0)
03170         {
03171             edt_msg(EDTLIB_MSG_FATAL, "Unable to lock front end unit %d channel %d at rate %d\n",
03172                 edt_p->unit_no, edt_p->channel_no, cfg->line_rate);
03173             rc = -1;
03174 
03175         }
03176     }
03177 
03178     FENTER_I("edt_ocx_configure", rc);
03179 
03180     return rc;
03181 
03182 }
03183 
03184 
03197 int
03198 edt_ocx_wait_for_frame(EdtDev *edt_p, int timeout)
03199 
03200 {
03201 
03202     if (edt_p->mezz.id == MEZZ_OC192 &&
03203         edt_p->channel_no & 1)
03204     {
03205         return edt_oc192_wait_for_frame(edt_p, timeout);
03206     } 
03207     else
03208     {
03209         return edt_ocm_wait_for_frame(edt_p, timeout);
03210     }
03211 }
03212 
03213 int
03214 edt_ocx_prepare_for_dma(EdtDev *edt_p, EdtOCConfig *cfg)
03215 
03216 {
03217 
03218     edt_reg_write(edt_p, PCD_CMD, 0);
03219     edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, FALSE);
03220 
03221 
03222     if (cfg->flags & EDT_OCX_WAIT_ON_SYNCH)
03223     {
03224 
03225     }
03226 
03227     if (cfg->writing)
03228     {
03229         edt_reg_write(edt_p, PCD_CMD, 8);
03230         edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, TRUE);
03231     }
03232 
03233     return 0;
03234 }
03235 
03236 int
03237 edt_ocx_post_start(EdtDev *edt_p, EdtOCConfig *cfg)
03238 
03239 {
03240 
03241     int rc = 0;
03242 
03243     if (!cfg->writing)
03244     {
03245         edt_reg_write(edt_p, PCD_CMD, 8);
03246         edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, TRUE);
03247     }
03248 
03249     /* wait for framed if collecting framed data */
03250     if ((cfg->flags & EDT_OCX_FRAMED) && edt_p->channel_no < 2)
03251     {
03252         rc = edt_ocx_wait_for_frame(edt_p, cfg->frame_timeout);
03253     }
03254 
03255     return rc;
03256 }
03257 
03258 int
03259 edt_ocx_channel_start_cfg(EdtDev *edt_p, EdtOCConfig *cfg, int n)
03260 
03261 {
03262     int rc = 0;
03263 
03264     FENTER("edt_ocx_channel_start_cfg");
03265 
03266     edt_ocx_prepare_for_dma(edt_p, cfg);
03267 
03268     edt_start_buffers(edt_p, n);
03269 
03270     rc = edt_ocx_post_start(edt_p, cfg);
03271 
03272 
03273     FRETURN("edt_ocx_channel_start_cfg");
03274 
03275     return 0;
03276 }
03277 
03278 int
03279 edt_ocx_adjust_phase(EdtDev *edt_p, int value)
03280 
03281 {
03282     int rc = 0;
03283 
03284     return rc;
03285 }
03286 
03287 
03299 int
03300 edt_ocx_channel_start(EdtDev *edt_p)
03301 
03302 {
03303 
03304     FENTER("edt_ocx_start");
03305 
03306     edt_msg(EDTLIB_MSG_INFO_1,"Start buffers\n");
03307 
03308     edt_start_buffers(edt_p, edt_p->ring_buffer_numbufs-1) ; /* start the transfers with all the allocated buffers */
03309 
03310     /* enable selected channel */
03311     edt_reg_write(edt_p, PCD_CMD, 8);
03312 
03313     edt_ocx_set_channel_enable(edt_p, edt_p->channel_no, TRUE);
03314 
03315     edt_msg(EDTLIB_MSG_INFO_1,"enabled\n");
03316 
03317 
03318     FRETURN("edt_ocx_start");
03319 
03320     return 0;
03321 }
03322 
03323 /* Convenience routines because 16 bit accesses seem
03324 to fail sometimes */
03325 
03326 static void
03327 edt_oc192_demux_set_mask_reg(EdtDev *edt_p, u_int reg, u_int column)
03328 
03329 {
03330     edt_reg_write(edt_p,OC192_DEMUX_BITMASK_LO, reg & 0xff);
03331     edt_reg_write(edt_p,OC192_DEMUX_BITMASK_HI, (reg >> 8) & 0xff);
03332     edt_reg_write(edt_p,OC192_DEMUX_MASK_ADDR, (0x80 + ( column >> 4 )));
03333 
03334 }
03335 
03336 static u_int
03337 edt_oc192_demux_get_mask_reg(EdtDev *edt_p, u_int column)
03338 
03339 {
03340     u_int reg;
03341 
03342     edt_reg_write(edt_p, OC192_DEMUX_MASK_ADDR, column >> 4);
03343 
03344     reg = edt_reg_read(edt_p,OC192_DEMUX_BITMASK_RD_LO);
03345     reg |= edt_reg_read(edt_p,OC192_DEMUX_BITMASK_RD_HI) << 8;
03346 
03347     return reg;
03348 
03349 }
03350 
03367 int
03368 edt_oc192_demux_set(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
03369 
03370 {
03371     int n = 192;
03372     int byte = 0;
03373     u_short bits[12];
03374     unsigned int reg;
03375 
03376     /* turn on all channels */
03377     memset(bits,0,sizeof(bits));
03378 
03379     if (line_rate != STM64_RATE && line_rate != OC192_RATE)
03380     {
03381         edt_msg(EDTLIB_MSG_FATAL,"Incorrect line rate %d for OC192\n", line_rate);
03382         return -1;
03383     }
03384 
03385     reg = 0;
03386 
03387     for (byte=0;byte < n; byte++)
03388     {
03389 
03390         reg = (reg << 1);
03391         reg += (onoff[byte])?0:1;
03392 
03393         if (byte % 16 == 15)
03394         {
03395             edt_oc192_demux_set_mask_reg(edt_p, reg, byte);
03396             reg = 0;
03397         }
03398     }
03399 
03400     return 0;
03401 }
03417 int
03418 edt_oc192_demux_get(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
03419 
03420 {
03421     int i = 0;
03422 
03423     if (line_rate != STM64_RATE && line_rate != OC192_RATE)
03424     {
03425         edt_msg(EDTLIB_MSG_FATAL,"Incorrect line rate %d for OC192\n", line_rate);
03426         return -1;
03427     }
03428 
03429     for (i=0;i<12;i++)
03430     {
03431         int j;
03432 
03433         int reg = edt_oc192_demux_get_mask_reg(edt_p, i << 4);
03434 
03435         for (j=0;j<16;j++)
03436             onoff[16 * i + j] = 1 ^ (1 & (reg >> (15-j)));
03437 
03438     }
03439 
03440 
03441     return 0;
03442 
03443 }
03444 
03461 int
03462 edt_oc192_demux_chan_enable(EdtDev *edt_p, int channel, int enable)
03463 
03464 {
03465     u_short bits;
03466     int shift = (0xf - (channel & 0xf));
03467     u_short mask;
03468 
03469     mask = (u_short) (1 << shift);
03470 
03471     /* get current register value */
03472 
03473 
03474     bits = (u_short) edt_oc192_demux_get_mask_reg(edt_p,channel);
03475 
03476     /* bit sense is 0 if on, 1 if off */
03477     if (enable)
03478         bits &= ~mask;
03479     else
03480         bits |= mask;
03481 
03482     /* write back out */
03483     edt_oc192_demux_set_mask_reg(edt_p, bits, channel);
03484 
03485     return 0;
03486 }
03487 
03502 int
03503 edt_oc192_demux_get_chan_enabled(EdtDev *edt_p, int channel)
03504 
03505 {
03506     u_short bits;
03507 
03508     int shift = (0xf - (channel & 0xf));
03509     u_short mask;
03510 
03511     mask = (u_short) (1 << shift);
03512 
03513     /* get current register value */
03514     bits = (u_short) edt_oc192_demux_get_mask_reg(edt_p,channel);
03515 
03516     /* bit sense is 0 if on, 1 if off */
03517 
03518     if (bits & mask)
03519         return 0;
03520     else
03521         return 1;
03522 
03523 }
03524 
03542 int
03543 edt_ocm_demux_set(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
03544 
03545 {
03546     int n = 48;
03547     int byte = 0;
03548     u_short bits[12];
03549     u_int bitmap_reg = OCM_CH0_DEMUX_BITMAP;
03550 
03551     /* turn on all channels */
03552     memset(bits,0,sizeof(bits));
03553 
03554     switch (line_rate) {
03555         case STM1_RATE:
03556         case OC3_RATE:
03557             n = 3;
03558 
03559             break;
03560         case STM4_RATE:
03561         case OC12_RATE:
03562             n = 12;
03563             break;
03564         case STM16_RATE:
03565         case OC48_RATE:
03566             n = 48;
03567             break;
03568 
03569         default:
03570             edt_msg(EDTLIB_MSG_FATAL,"Incorrect line rate %d for OCM demux\n", line_rate);
03571             return -1;
03572 
03573     }
03574 
03575     if (edt_p->channel_no)
03576         bitmap_reg = OCM_CH1_DEMUX_BITMAP;
03577 
03578     /* cycle through oring in bits - bit 3 of byte 0 is first channel,
03579     bit 0 of last byte is last channel */
03580 
03581     /* bit sense is 0 enabled, 1 disabled */
03582 
03583     for (byte=0; byte < n; )
03584     {
03585         int val = 0;
03586         int bit;
03587 
03588         for (bit = 0;bit < 4;bit++)
03589             val = (val << 1) | ((onoff[byte++]) ? 0 : 1);
03590 
03591         val |= (((byte-1) >> 2) << 4) ;
03592 
03593         edt_reg_write(edt_p, bitmap_reg, val);
03594 
03595     }
03596 
03597     return 0;
03598 }
03615 int
03616 edt_ocm_demux_get(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
03617 
03618 {
03619     int n = 48;
03620     int i = 0;
03621     u_short bits[12];
03622     u_int bitmap_reg = OCM_CH0_DEMUX_BITMAP_READ;
03623 
03624     switch (line_rate) {
03625         case STM1_RATE:
03626         case OC3_RATE:
03627             n = 3;
03628 
03629             break;
03630         case STM4_RATE:
03631         case OC12_RATE:
03632             n = 12;
03633             break;
03634         case STM16_RATE:
03635         case OC48_RATE:
03636             n = 48;
03637             break;
03638 
03639         default:
03640             edt_msg(EDTLIB_MSG_FATAL,"Incorrect line rate %d for OCM demux\n", line_rate);
03641             return -1;
03642 
03643     }
03644 
03645     if (edt_p->channel_no)
03646         bitmap_reg = OCM_CH1_DEMUX_BITMAP_READ;
03647 
03648     for (i=0;i<(n+3)/4;i++)
03649     {
03650         edt_reg_write(edt_p, bitmap_reg, i<<4);
03651         bits[i] = (u_short) edt_reg_read(edt_p, bitmap_reg);
03652     }
03653 
03654     for (i=0;i < n; i++)
03655     {
03656         int whichbyte = i / 4;
03657         int shift = (3 - (i & 3));
03658 
03659         onoff[i] = (u_char) !(bits[whichbyte] & (1 << shift));
03660 
03661     }
03662 
03663     return 0;
03664 
03665 }
03666 
03680 int
03681 edt_ocm_demux_chan_enable(EdtDev *edt_p, int channel, int enable)
03682 
03683 {
03684     u_short bits;
03685     int whichbyte = channel / 4;
03686     int shift = (3 - (channel & 3));
03687     u_short mask;
03688     u_int bitmap_reg = OCM_CH0_DEMUX_BITMAP_READ;
03689 
03690     mask = 1 << shift;
03691     if (edt_p->channel_no)
03692         bitmap_reg = OCM_CH1_DEMUX_BITMAP_READ;
03693 
03694     /* get current register value */
03695 
03696     edt_reg_write(edt_p, bitmap_reg, whichbyte << 4);
03697     bits = edt_reg_read(edt_p, bitmap_reg) & 0xf;
03698 
03699     /* bit sense is 0 if on, 1 if off */
03700     if (enable)
03701         bits &= ~mask;
03702     else
03703         bits |= mask;
03704 
03705     /* select demux write register */
03706 
03707     bitmap_reg = (edt_p->channel_no)? OCM_CH1_DEMUX_BITMAP: OCM_CH0_DEMUX_BITMAP;
03708 
03709     bits |= (whichbyte << 4);
03710 
03711     /* write back out */
03712     edt_reg_write(edt_p, bitmap_reg, bits);
03713 
03714     return 0;
03715 }
03716 
03731 int
03732 edt_ocm_demux_get_chan_enabled(EdtDev *edt_p, int channel)
03733 
03734 {
03735     u_short bits;
03736     int whichbyte = channel / 4;
03737     int shift = (3 - (channel & 3));
03738     u_short mask;
03739     u_int bitmap_reg = OCM_CH0_DEMUX_BITMAP_READ;
03740 
03741     mask = 1 << shift;
03742     if (edt_p->channel_no)
03743         bitmap_reg = OCM_CH1_DEMUX_BITMAP_READ;
03744 
03745     /* get current register value */
03746 
03747     edt_reg_write(edt_p, bitmap_reg, whichbyte << 4);
03748     bits = edt_reg_read(edt_p, bitmap_reg) & 0xf;
03749 
03750     if (bits & mask)
03751         return 0;
03752     else
03753         return 1;
03754 
03755 }
03756 
03774 int
03775 edt_ocx_demux_set(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
03776 
03777 {
03778     if (edt_p->mezz.id == 0xffff)
03779         edt_get_board_description(edt_p, TRUE);
03780 
03781     if (edt_p->mezz.id == MEZZ_OC192 && edt_p->channel_no == 1)
03782     {
03783         return edt_oc192_demux_set(edt_p, line_rate, onoff);
03784     }
03785     else
03786     {
03787         return edt_ocm_demux_set(edt_p, line_rate, onoff);
03788     }
03789 }
03790 
03809 int
03810 edt_ocx_demux_get(EdtDev *edt_p, EdtLineRate line_rate, u_char *onoff)
03811 
03812 {
03813     if (edt_p->mezz.id == MEZZ_OC192 && edt_p->channel_no == 1)
03814     {
03815         return edt_oc192_demux_get(edt_p, line_rate, onoff);
03816     }
03817     else
03818     {
03819         return edt_ocm_demux_get(edt_p, line_rate, onoff);
03820     }
03821 
03822 }
03823 
03838 int
03839 edt_ocx_demux_chan_enable(EdtDev *edt_p, int channel, u_char enable)
03840 
03841 {
03842     if (edt_p->mezz.id == MEZZ_OC192 && edt_p->channel_no == 1)
03843     {
03844         return edt_oc192_demux_chan_enable(edt_p, channel, enable);
03845     }
03846     else
03847     {
03848         return edt_ocm_demux_chan_enable(edt_p, channel, enable);
03849     }
03850 }
03851 
03867 int
03868 edt_ocx_demux_get_chan_enabled(EdtDev *edt_p, int channel)
03869 
03870 {
03871     if (edt_p->mezz.id == MEZZ_OC192 && edt_p->channel_no == 1)
03872     {
03873         return edt_oc192_demux_get_chan_enabled(edt_p, channel);
03874     }
03875     else
03876     {
03877         return edt_ocm_demux_get_chan_enabled(edt_p, channel);
03878     }
03879 }
03880 
03881 
03882 /*
03883 * read and print the contents of the auto phase adjust that sets
03884 * up the sample point for the receive clock where the capability exists
03885 */
03886 
03887 int edt_ocx_print_auto_phase(EdtDev *edt_p)
03888 {
03889     int channel = edt_p->channel_no & 1;
03890     int base_offset = 0;
03891     int mezzanine_offset = 0;
03892     int freq = 0;
03893     u_char read_byte, ctrl_reg;
03894 
03895     FENTER("edt_ocx_print_auto_phase");
03896     if (edt_p->mezz.id == MEZZ_OCM)
03897     {
03898         if (edt_ocm_has_mezz_bitfile(edt_p, "ethernet.bit") == 0)
03899         {
03900             if (channel == 1)
03901             {
03902                 base_offset = OFFSET_CH1_BASE;
03903                 mezzanine_offset = OFFSET_CH1_MEZ;
03904             }
03905 
03906             /* write the control register to select normal status */
03907             ctrl_reg = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset);
03908             ctrl_reg &= ~STAT_SEL_MSK;
03909             ctrl_reg |= SIG_STAT;
03910             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
03911             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
03912             printf("RXCLK STAT %02x -", read_byte);
03913             if (read_byte & NO_RXCLK)
03914                 printf("No receive clock present, ");
03915             else
03916                 printf("Receive clock present, ");
03917             if (read_byte & PHASE_OVF)
03918                 printf("DCM phase overflow, ");
03919             if (read_byte & DCM_LOCK_SET)
03920                 printf("DCM locked, ");
03921             else
03922                 printf("DCM not locked, ");
03923             printf("auto state is %d, sample clock is %d\n", (read_byte & DONE_STATE_MSK) >> 2,
03924                 (read_byte & (CLK_F | CLK_R)) );
03925             ctrl_reg &= ~STAT_SEL_MSK;
03926             ctrl_reg |= CLK_POS_START;
03927             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
03928             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
03929             printf("First positive edge - %d\n", read_byte);
03930             ctrl_reg &= ~STAT_SEL_MSK;
03931             ctrl_reg |= CLK_NEG_EDGE;
03932             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
03933             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
03934             printf("Negative edge - %d\n", read_byte);
03935             ctrl_reg &= ~STAT_SEL_MSK;
03936             ctrl_reg |= CLK_NXT_POS;
03937             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
03938             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
03939             printf("Next positive edge - %d\n", read_byte);
03940             ctrl_reg &= ~STAT_SEL_MSK;
03941             ctrl_reg |= CLK_FINAL;
03942             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
03943             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
03944             printf("Final auto set position - %d\n", read_byte);
03945             ctrl_reg &= ~STAT_SEL_MSK;
03946             ctrl_reg |= SHADOW_CNT;
03947             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, ctrl_reg);
03948             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
03949             printf("Current position - %d\n", read_byte);
03950         }
03951     }
03952 
03953     FRETURN_I("edt_ocx_print_auto_phase", 0);
03954     return 0;
03955 }
03956 
03957 /*
03958 * read frequency counter - only supported on ocm ethernet at this time
03959 * return channel bitrate in MHz
03960 */
03961 int edt_ocx_read_frequency(EdtDev *edt_p, EdtOCConfig *cfg)
03962 {
03963     int channel = edt_p->channel_no & 1;
03964     int base_offset = 0;
03965     int mezzanine_offset = 0;
03966     int freq = 0;
03967     u_char read_byte;
03968 
03969     FENTER("edt_ocx_read_frequency");
03970     if (edt_p->mezz.id == MEZZ_OCM)
03971     {
03972         if (edt_ocm_has_mezz_bitfile(edt_p, "ethernet.bit") == 0)
03973         {
03974             if (channel == 1)
03975             {
03976                 base_offset = OFFSET_CH1_BASE;
03977                 mezzanine_offset = OFFSET_CH1_MEZ;
03978             }
03979 
03980             /* write the clear bit to one  after making sure it is zero */
03981             read_byte = edt_reg_read(edt_p,  OCM_CH0_FREQ_CNT_CTRL + mezzanine_offset);
03982             read_byte &= ~CLEAR_VALID;
03983             edt_reg_write(edt_p,  OCM_CH0_FREQ_CNT_CTRL + mezzanine_offset, read_byte);
03984             read_byte |= CLEAR_VALID;
03985             edt_reg_write(edt_p,  OCM_CH0_FREQ_CNT_CTRL + mezzanine_offset, read_byte);
03986             read_byte &= ~CLEAR_VALID;
03987             edt_reg_write(edt_p,  OCM_CH0_FREQ_CNT_CTRL + mezzanine_offset, read_byte);
03988             /* wait for valid to set (100us) */
03989             while ( ((read_byte = edt_reg_read(edt_p, OCM_CH0_FREQ_STATUS + mezzanine_offset)) & FREQ_VALID) == 0) ;
03990             freq = (int) edt_reg_read( edt_p, OCM_CH0_FREQUENCY + mezzanine_offset);
03991             /* calculate frequency in MHz
03992             * Frequency counter counts 0 as the first count
03993             * the internal FPGA read  clock is divided by 4 in the SLK2511 and then by 2 in the FPGA
03994             * gate is 100us so Hz is times 10000 but MHz is divide by 100
03995             */
03996             freq = ((freq+1) * 8)/ 100; 
03997 
03998             return freq;
03999         }
04000     }
04001 
04002     FRETURN_I("edt_ocx_read_frequency",-1);
04003     return -1;
04004 }
04005 
04006 
04007 /*
04008 * change the clock phase plus or minus the amount
04009 * passed in change
04010 */
04011 int edt_ocx_rx_clk_phase(EdtDev *edt_p, int change)
04012 {
04013     int channel = edt_p->channel_no & 1;
04014     int base_offset = 0;
04015     int mezzanine_offset = 0;
04016     int current_count = 0;
04017     u_char read_byte;
04018 
04019     FENTER("edt_ocx_rx_clk_phase");
04020     if (edt_p->mezz.id == MEZZ_OCM)
04021     {
04022         if (edt_ocm_has_mezz_bitfile(edt_p, "ethernet.bit") == 0)
04023         {
04024             if (channel == 1)
04025             {
04026                 base_offset = OFFSET_CH1_BASE;
04027                 mezzanine_offset = OFFSET_CH1_MEZ;
04028             }
04029 
04030             /* read the current position from the shadow count */
04031             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset);
04032             read_byte &= ~(PRG_PS_EN | STAT_SEL_MSK) ; /* reset the ps_en if set */
04033             read_byte |= SHADOW_CNT;
04034             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04035             /* read the count */
04036             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04037             current_count = (int) (read_byte & 0xff); /* make it an int */
04038             if ( (current_count + change) < 0)
04039             {
04040                 /*
04041                 printf("Proposed RXCLK phase change %d to %d makes final < 0, setting phase to 0\n",
04042                 change, current_count);
04043                 */
04044                 change = - current_count;
04045             }
04046             if ( (current_count + change) > 255)
04047             {
04048                 /*
04049                 printf("Proposed RXCLK phase change %d to %d makes final > 255, setting phase to  max at 255\n",
04050                 change, current_count);
04051                 */
04052                 change = - current_count;
04053             }
04054             /* set to increment if change is positive  and set status read to basic status */
04055             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset);
04056             read_byte &= ~STAT_SEL_MSK ;
04057             read_byte |= SIG_STAT ; 
04058             if (change > 0) 
04059             {
04060                 read_byte |=  PRG_PS_INC;
04061             }
04062             else
04063             {
04064                 read_byte &=  ~PRG_PS_INC;
04065                 change = -change;
04066             }
04067             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04068             while(change--)
04069             {
04070                 /* inc/dec by one - strobe ps_en */
04071                 read_byte |= PRG_PS_EN;
04072                 edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04073                 read_byte &= ~PRG_PS_EN;
04074                 edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04075                 /* wait until the state machine comes back to the done state */
04076                 while (((edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset)) & DONE_STATE_MSK) != STATE_DONE);
04077             }
04078             /* read the current shadow count and return */
04079             read_byte &= ~STAT_SEL_MSK ;
04080             read_byte |= SHADOW_CNT;
04081             edt_reg_write(edt_p,  OCM_CH0_RX_CLK_CTRL + mezzanine_offset, read_byte);
04082             /* read the count */
04083             read_byte = edt_reg_read(edt_p,  OCM_CH0_RX_CLK_STAT + mezzanine_offset);
04084             FRETURN_I("edt_ocx_rx_clk_phase", read_byte);
04085             return(read_byte);
04086         }
04087     }
04088 
04089     FRETURN_I("edt_ocx_rx_clk_phase",-1);
04090     return -1;
04091 }
04092 
04093 int
04094 edt_ocx_clear_demux(EdtOcxDemux *demux)
04095 
04096 {
04097     memset(demux, 0, sizeof(EdtOcxDemux));
04098     return 0;
04099 }
04100 
04101 int
04102 edt_ocx_parse_demux(EdtOcxDemux *demux, char *word, char *errorstr)
04103 
04104 {
04105 
04106     u_char DCBA[4];
04107     int len = 0;
04108     int maxlen = 4;
04109     char *cp = word;
04110     int disable = FALSE;
04111     int i;
04112     u_char *pvec;
04113     int off;
04114 
04115     memset(DCBA,0,sizeof(DCBA));
04116 
04117     switch (demux->rate)
04118     {
04119     case 1:
04120     case 3:
04121         maxlen = 1;          
04122         break;
04123 
04124     case 4:
04125     case 12:
04126         maxlen = 2;
04127         break;
04128     case 16:
04129     case 48:
04130         maxlen = 3;
04131         break;
04132     case 64:
04133     case 192:
04134         maxlen = 4;
04135         break;
04136     }
04137 
04138     /* remove parens and commas */
04139 
04140     if (*cp == '-') 
04141     {
04142         disable = TRUE;
04143         cp++;
04144     }
04145 
04146     if (*cp == '(')
04147         cp++;
04148 
04149     while (*cp && *cp != ')' && len < 4)
04150     {
04151         if (*cp >= '0' && *cp <= '4')
04152         {
04153             DCBA[len] = *cp - '0';
04154             len++;
04155         }
04156         else
04157         {
04158             sprintf(errorstr, "Unexpected character %c at %d in %s, should be 0-4\n",
04159                 *cp, cp - word, word);
04160             return -1;
04161 
04162         }
04163 
04164         cp++;
04165         if (*cp == ',')
04166             cp++;
04167         else if (*cp && *cp != ')')
04168         {
04169             sprintf(errorstr, "Unexpected character %c at %d in %s\n",
04170                 *cp, cp - word, word);
04171             return -1;
04172         }
04173     }
04174 
04175 
04176     if (len > maxlen)
04177     {
04178         sprintf(errorstr, "STM-%d can only have %d value%s in notation\n", demux->rate,maxlen,(maxlen > 1)?"s":"");
04179         return -1;
04180     }
04181 
04182     if (DCBA[maxlen-1] == 4)
04183     {
04184         sprintf(errorstr, "STM-%d last value should be 1-3 in %s\n", demux->rate, word);
04185         return -1;
04186     }
04187 
04188     sprintf(errorstr, "DCBA = (");
04189     for (i=0;i<maxlen-1;i++)
04190         sprintf(errorstr + strlen(errorstr), "%d,", DCBA[i]);
04191     sprintf(errorstr + strlen(errorstr), "%d)\n", DCBA[maxlen-1]);
04192 
04193     if (disable)
04194         pvec = demux->disable;
04195     else
04196         pvec = demux->enable;
04197 
04198     switch (demux->rate)
04199     {
04200     case 1:
04201     case 3:
04202         break;
04203 
04204     case 4:
04205     case 12:
04206         if (DCBA[0] == 0)
04207         {
04208             for (i=0;i<12;i++)
04209                 pvec[i] = 1;
04210         }
04211         else if (DCBA[1] == 0)
04212         {
04213             /* STM-1 (vC-4) */
04214             off = (DCBA[0]-1);
04215             pvec[off] = 1;
04216             pvec[off+4] = 1;
04217             pvec[off+8] = 1;
04218             sprintf(errorstr + strlen(errorstr), "STM-1 # %d\n", off+1);
04219         }
04220         else
04221         {
04222             off = (DCBA[0]-1) + 4 * (DCBA[1]-1);
04223             pvec[off] = 1;
04224             sprintf(errorstr + strlen(errorstr), "STM-0 # %d\n", off+1);
04225         }
04226         break;
04227 
04228     case 16:
04229     case 48:
04230         if (DCBA[0] == 0)
04231         {
04232             for (i=0;i<48;i++)
04233                 pvec[i] = 1;
04234         }
04235         else if (DCBA[1] == 0)
04236         {
04237             /* STM-4 (vC-4-4c) */
04238             off = 4 * (DCBA[0]-1);
04239             for (i=0;i<4;i++)
04240             {
04241                 pvec[off+i] = 1;
04242                 pvec[off+16+i] = 1;
04243                 pvec[off+32+i] = 1;
04244             }
04245             sprintf(errorstr + strlen(errorstr), "STM-4 # %d\n", off/4 + 1);
04246         }
04247         else if (DCBA[2] == 0)
04248         {
04249             /* STM-1 (vC-4) */
04250             off = 4 * (DCBA[0]-1) + (DCBA[1]-1);
04251             pvec[off] = 1;
04252             pvec[off+16] = 1;
04253             pvec[off+32] = 1;
04254             sprintf(errorstr + strlen(errorstr), "STM-1 # %d\n", off+1);
04255         }
04256         else
04257         {
04258             off = 4 * (DCBA[0]-1) + (DCBA[1]-1) + 16 * (DCBA[2]-1);
04259             pvec[off] = 1;
04260             sprintf(errorstr + strlen(errorstr), "STM-0 # %d\n", off+1);
04261         }
04262         break;
04263 
04264     case 64:
04265     case 192:
04266         if (DCBA[0] == 0)
04267         {
04268             for (i=0;i<192;i++)
04269                 pvec[i] = 1;
04270             sprintf(errorstr + strlen(errorstr), "STM-64 \n");
04271         }
04272         else if (DCBA[1] == 0)
04273         {
04274             /* STM-16 (vC-4-16c) */
04275             off = 16 * (DCBA[0]-1);
04276             for (i=0;i<16;i++)
04277             {
04278                 pvec[off+i] = 1;
04279                 pvec[off+64+i] = 1;
04280                 pvec[off+128+i] = 1;
04281             }     
04282             sprintf(errorstr + strlen(errorstr), "STM-16 # %d\n", off / 16 + 1);
04283         }
04284         else if (DCBA[2] == 0)
04285         {
04286             /* STM-4 (vC-4-4c) */
04287             off = 16 * (DCBA[0]-1) + 4 * (DCBA[1]-1);
04288             for (i=0;i<4;i++)
04289             {
04290                 pvec[off+i] = 1;
04291                 pvec[off+64+i] = 1;
04292                 pvec[off+128+i] = 1;
04293             }
04294             sprintf(errorstr + strlen(errorstr), "STM-4 # %d\n", off/4 + 1);
04295         }
04296         else if (DCBA[3] == 0)
04297         {
04298             /* STM-1 (vC-4) */
04299             off = 16 * (DCBA[0]-1) + 4 * (DCBA[1]-1) + (DCBA[2]-1);
04300             pvec[off] = 1;
04301             pvec[off+64] = 1;
04302             pvec[off+128] = 1;
04303             sprintf(errorstr + strlen(errorstr), "STM-1 # %d\n", off+1);
04304         }
04305         else
04306         {
04307             off = 16 * (DCBA[0]-1) + 4 * (DCBA[1]-1) + (DCBA[2]-1) + 64 * (DCBA[3]-1);
04308             pvec[off] = 1;
04309             sprintf(errorstr + strlen(errorstr), "STM-0 # %d\n", off+1);
04310         }
04311         break;
04312 
04313 
04314     }
04315 
04316     return 0;
04317 }
04318 
04319 void edt_ocx_print_byte_array(char *tag, u_char *pvec, int n)
04320 
04321 {
04322     int on = 0;
04323     int start = 0;
04324 
04325     int i;
04326 
04327     printf("%-10s: ", tag);
04328 
04329     for (i=0;i<n;i++)
04330     {
04331         if ((pvec[i] &&  !on) ||
04332             (!pvec[i] && on))
04333         {
04334             if (on)
04335             {
04336                 if (start == i-1)
04337                     printf("%d ", i-1);
04338                 else
04339                     printf("%d-%d ", start, i-1);
04340             }
04341             else
04342             {
04343                 start = i;
04344             }
04345 
04346             on = !on;
04347         }
04348         else if ((i == n-1) && on)
04349         {
04350             printf("%d-%d ", start, i);
04351 
04352         }
04353     }
04354 
04355     printf("\n");
04356 
04357 }
04358 
04359 int edt_ocx_demux_print(EdtOcxDemux *demux)
04360 
04361 {
04362     int n = 3 * demux->rate;
04363 
04364     int i;
04365 
04366 
04367     edt_ocx_print_byte_array("Current", demux->current_values, n);
04368     edt_ocx_print_byte_array("Enable", demux->enable, n);
04369     edt_ocx_print_byte_array("Disable", demux->disable, n);
04370 
04371     return 0;
04372 
04373 }
04374 

Generated on Mon Mar 21 14:14:42 2011 by  doxygen 1.4.7