@@ -1850,6 +1850,12 @@ static int qsfp_fsm_poll_los (bf_dev_id_t dev_id,
18501850 return -1 ;
18511851 }
18521852
1853+ // skip trigger quick removal action until everything goes right.
1854+ if (platform_type_equal (AFN_X312PT ) &&
1855+ (bf_pltfm_mgr_ctx ()-> flags & AF_PLAT_CTRL_HA_MODE )) {
1856+ return 0 ;
1857+ }
1858+
18531859 // CPLD told us this module is absent.
18541860 // Donot move FSM until removal is hanlded
18551861 //if (!bf_qsfp_is_present (conn_id)) {
@@ -1879,10 +1885,23 @@ static int qsfp_fsm_poll_los (bf_dev_id_t dev_id,
18791885 }
18801886
18811887 if (rc ) {
1888+ // skip trigger quick removal action and disable chassis monitor.
1889+ // requires maunally op via command chassis-ctrlmask-set if everything goes right.
1890+ // Query the QSFP library for the qsfp presence mask
1891+ if (platform_type_equal (AFN_X312PT )) {
1892+ uint32_t lower_mask , upper_mask , cpu_mask ;
1893+ if (bf_qsfp_get_transceiver_pres (& lower_mask ,
1894+ & upper_mask , & cpu_mask ) != 0 ) {
1895+ bf_pltfm_mgr_ctx ()-> flags |= AF_PLAT_CTRL_HA_MODE ;
1896+ return 0 ;
1897+ }
1898+ }
1899+
18821900 /* Added by tsihang, 2023-03-21. */
18831901 // Detect and latch the removal
18841902 // state, so that can qsfp-scan handle the rest.
1885- if (!qsfp_state [conn_id ].qsfp_quick_removed ) {
1903+ if (!platform_type_equal (AFN_X312PT ) &&
1904+ !qsfp_state [conn_id ].qsfp_quick_removed ) {
18861905 bool is_present = 0 ;
18871906 bf_qsfp_detect_transceiver (conn_id , & is_present );
18881907 if (!is_present ) {
@@ -2295,12 +2314,13 @@ static void qsfp_module_fsm_run (bf_dev_id_t
22952314 }
22962315 qsfp_state [conn_id ].qsfp_quick_removed = false;
22972316
2317+ // checks for QSFPs with "special" requirements
2318+ qsfp_fsm_identify_model_requirements (conn_id );
2319+ bf_qsfp_ctrlmask_get (conn_id , & ctrlmask );
2320+
22982321 if (is_optical ) {
22992322 int ch ;
23002323
2301- // checks for QSFPs with "special" requirements
2302- qsfp_fsm_identify_model_requirements (conn_id );
2303-
23042324 // set initial state for each of the 4 channel FSMs
23052325 for (ch = 0 ; ch < CHANNEL_COUNT ; ch ++ ) {
23062326 qsfp_state [conn_id ].per_ch_fsm [ch ] =
@@ -2313,6 +2333,12 @@ static void qsfp_module_fsm_run (bf_dev_id_t
23132333 } else {
23142334 LOG_WARNING ("QSFP %2d : NOT OPTICAL ..." ,
23152335 conn_id );
2336+ /* Trigger high power mode. */
2337+ if (ctrlmask & BF_TRANS_CTRLMASK_REQUIRE_HIGH_PWR_MODE ) {
2338+ LOG_WARNING ("QSFP %2d : trigger high power mode for module ..." ,
2339+ conn_id );
2340+ qsfp_luxtera_hipwr (conn_id , bf_qsfp_is_cmis (conn_id ));
2341+ }
23162342 if (bf_pm_intf_is_device_family_tofino (dev_id )) {
23172343 qsfp_fsm_notify_bf_pltfm (dev_id , conn_id );
23182344 }
@@ -4874,6 +4900,93 @@ void qsfp_luxtera_lpbk (int conn_id,
48744900 near_lpbk ? "NEAR/ELEC." : "FAR/OPTICAL" );
48754901}
48764902
4903+ /*****************************************************************
4904+ *
4905+ *****************************************************************/
4906+ void qsfp_luxtera_hipwr (int conn_id ,
4907+ bool is_cmis )
4908+ {
4909+ uint8_t pwd [] = {0x00 , 0x00 , 0x10 , 0x11 };
4910+ uint8_t wr [] = {0x10 , 0x10 , 0x10 , 0x00 };
4911+ uint8_t rd [] = {0x00 , 0x00 , 0x00 , 0x00 };
4912+ uint8_t pwr_class = 0x08 , output_enb = 0x01 ;
4913+ uint8_t pg0 = 0x0 , pg2 = 0x2 ;
4914+ int rc ;
4915+
4916+ if (!is_cmis ) {
4917+ rc = bf_fsm_qsfp_wr2 (conn_id , pg0 , 0x7b , 4 , pwd );
4918+ if (rc ) {
4919+ LOG_WARNING (
4920+ "QSFP %2d : Error <%d> Setting pwd for high power mode" ,
4921+ conn_id , rc );
4922+ return ;
4923+ }
4924+ }
4925+
4926+ if (is_cmis ) {
4927+ rc = bf_fsm_qsfp_wr2 (conn_id , pg0 , 0xc8 , 1 ,
4928+ & pwr_class );
4929+ } else {
4930+ rc = bf_fsm_qsfp_wr2 (conn_id , pg2 , 0x8b , 1 ,
4931+ & output_enb );
4932+ rc = bf_fsm_qsfp_wr2 (conn_id , pg2 , 0x82 , 4 ,
4933+ wr );
4934+ }
4935+ if (rc ) {
4936+ LOG_WARNING ("QSFP %2d : Error <%d> Setting high power mode" ,
4937+ conn_id ,
4938+ rc );
4939+ return ;
4940+ }
4941+
4942+ if (is_cmis ) {
4943+ rc = bf_fsm_qsfp_rd2 (conn_id , pg0 , 0xc8 , 1 , & rd [0 ]);
4944+ if (rc ) {
4945+ LOG_WARNING ("QSFP %2d : Error <%d> Reading byte 0xC8 for high power mode" ,
4946+ conn_id ,
4947+ rc );
4948+ return ;
4949+ }
4950+ if (rd [0 ] != pwr_class ) {
4951+ LOG_WARNING ("QSFP %2d : Error <%d> Setting byte 0xC8 for high power mode" ,
4952+ conn_id ,
4953+ rc );
4954+ return ;
4955+ }
4956+ } else {
4957+ rc = bf_fsm_qsfp_rd2 (conn_id , pg2 , 0x8b , 1 , & rd [0 ]);
4958+ if (rc ) {
4959+ LOG_WARNING ("QSFP %2d : Error <%d> Reading byte 0x8B for high power mode" ,
4960+ conn_id ,
4961+ rc );
4962+ return ;
4963+ }
4964+ if (rd [0 ] != output_enb ) {
4965+ LOG_WARNING ("QSFP %2d : Error <%d> Setting byte 0x8B for high power mode" ,
4966+ conn_id ,
4967+ rc );
4968+ return ;
4969+ }
4970+ rc = bf_fsm_qsfp_rd2 (conn_id , pg2 , 0x82 , 4 , & rd [0 ]);
4971+ if (rc ) {
4972+ LOG_WARNING ("QSFP %2d : Error <%d> Reading byte 0x8B for high power mode" ,
4973+ conn_id ,
4974+ rc );
4975+ return ;
4976+ }
4977+ if ((rd [0 ] != wr [0 ]) ||
4978+ (rd [1 ] != wr [1 ]) ||
4979+ (rd [2 ] != wr [2 ]) ||
4980+ (rd [3 ] != wr [3 ])) {
4981+ LOG_WARNING ("QSFP %2d : Error <%d> Setting byte 0x82-0x85 for high power mode" ,
4982+ conn_id ,
4983+ rc );
4984+ return ;
4985+ }
4986+ }
4987+ LOG_DEBUG ("QSFP %2d : High power mode set." , conn_id );
4988+ }
4989+
48774990bool bf_pm_qsfp_is_luxtera (int conn_id )
48784991{
48794992 if (qsfp_needs_hi_pwr_init (conn_id )) {
0 commit comments