openbcm

Git mirror of https://github.com/Broadcom-Network-Switching-Software/OpenBCM
git clone git://git.finwo.net/mirror/broadcom/openbcm
Log | Files | Refs | README

furia_82212.c (35165B)


      1 /*
      2  *         
      3  * 
      4  * 
      5  * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file.
      6  * 
      7  * Copyright 2007-2019 Broadcom Inc. All rights reserved.
      8  */
      9 
     10 #include <phymod/phymod.h>
     11 #include <phymod/phymod_system.h>
     12 #include <phymod/phymod_dispatch.h>
     13 
     14 #ifdef PHYMOD_FURIA_SUPPORT
     15 #include <phymod/chip/furia.h>
     16 #include "../../furia/tier1/furia_regs_structs.h"
     17 #include "../../furia/tier1/furia_reg_access.h"
     18 #include "../../furia/tier1/furia_address_defines.h"
     19 #include "../../furia/tier1/furia_micro_seq.h"
     20 #include "../../furia/tier1/furia_types.h"
     21 #include "../../furia/tier1/furia_cfg_seq.h"
     22 #include "furia_82212_helper.h"
     23 
     24 int furia_82212_core_identify(const phymod_core_access_t* core, uint32_t core_id, uint32_t* is_identified)
     25 {
     26     int ioerr = 0;
     27     const phymod_access_t *pm_acc = &core->access;
     28     IEEE_PMA_PMD_BLK0_PMD_IDENTIFIER_REGISTER_0_t id2;
     29     IEEE_PMA_PMD_BLK0_PMD_IDENTIFIER_REGISTER_1_t id3; 
     30     uint32_t chip_id = 0;
     31     chip_id =  _furia_get_chip_id(pm_acc);
     32 
     33     *is_identified = 0;
     34 
     35     if(core_id == 0){
     36         ioerr += 
     37         READ_FURIA_PMA_PMD_REG(pm_acc,
     38                                IEEE_PMA_PMD_BLK0_pmd_identifier_register_0_Adr,
     39                                &id2.data);  
     40         ioerr += 
     41         READ_FURIA_PMA_PMD_REG(pm_acc,
     42                                IEEE_PMA_PMD_BLK0_pmd_identifier_register_1_Adr,
     43                                &id3.data);  
     44     } else {
     45         id2.data = (uint16_t) ((core_id >> 16) & 0xffff);
     46         id3.data = (uint16_t) core_id & 0xffff;
     47     }
     48 
     49     if (((id2.data) == FURIA_ID0 &&
     50         (id3.data) == FURIA_ID1) && (chip_id == FURIA_ID_82212)) {
     51 
     52         /* PHY IDs match */
     53         *is_identified = 1;
     54     }
     55         
     56     return ioerr ? PHYMOD_E_IO : PHYMOD_E_NONE;    
     57 }
     58 
     59 
     60 int furia_82212_core_info_get(const phymod_core_access_t* core, phymod_core_info_t* info)
     61 {
     62     PHYMOD_IF_ERR_RETURN(furia_core_info_get(core,info)); 
     63     
     64     return PHYMOD_E_NONE;
     65     
     66 }
     67 
     68 
     69 int furia_82212_core_reset_set(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t direction)
     70 {
     71     phymod_core_access_t core_cpy;
     72     uint16_t die_idx = 0;
     73     PHYMOD_MEMSET(&core_cpy, 0, sizeof(phymod_core_access_t));
     74     PHYMOD_MEMCPY(&core_cpy, core, sizeof(phymod_core_access_t));
     75    
     76     core_cpy.access.addr &= (~1);
     77     for (die_idx = 0; die_idx < FURIA_82212_MAX_DIE; die_idx ++) {
     78         core_cpy.access.addr |= die_idx;
     79 
     80         PHYMOD_IF_ERR_RETURN(
     81            furia_core_reset_set(&core_cpy, reset_mode, direction));
     82     }
     83     
     84     return PHYMOD_E_NONE;
     85     
     86 }
     87 
     88 int furia_82212_core_reset_get(const phymod_core_access_t* core, phymod_reset_mode_t reset_mode, phymod_reset_direction_t* direction)
     89 {
     90     return PHYMOD_E_UNAVAIL;
     91 }
     92 
     93 
     94 int furia_82212_core_firmware_info_get(const phymod_core_access_t* core, phymod_core_firmware_info_t* fw_info)
     95 {
     96      PHYMOD_IF_ERR_RETURN(
     97          furia_core_firmware_info_get(core, fw_info));
     98     
     99     return PHYMOD_E_NONE;
    100     
    101 }
    102 
    103 
    104 int furia_82212_phy_firmware_core_config_set(const phymod_phy_access_t* phy, phymod_firmware_core_config_t fw_core_config)
    105 {
    106     return PHYMOD_E_NONE;
    107     
    108 }
    109 
    110 int furia_82212_phy_firmware_core_config_get(const phymod_phy_access_t* phy, phymod_firmware_core_config_t* fw_core_config)
    111 {
    112         
    113     return PHYMOD_E_NONE;
    114     
    115 }
    116 
    117 int furia_82212_phy_firmware_lane_config_set(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t fw_lane_config)
    118 {
    119     phymod_phy_access_t phy_cpy;
    120     uint16_t lane_idx = 0;
    121     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    122     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    123    
    124     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    125         if (phy->access.lane_mask & (1 << lane_idx)) {
    126             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    127                   furia_phy_firmware_lane_config_set(&phy_cpy, fw_lane_config));
    128         }
    129     }
    130    
    131     return PHYMOD_E_NONE;
    132     
    133 }
    134 
    135 int furia_82212_phy_firmware_lane_config_get(const phymod_phy_access_t* phy, phymod_firmware_lane_config_t* fw_lane_config)
    136 {
    137     phymod_phy_access_t phy_cpy;
    138     uint16_t lane_idx = 0;
    139     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    140     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    141    
    142     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    143         if (phy->access.lane_mask & (1 << lane_idx)) {
    144             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    145                   furia_phy_firmware_lane_config_get(&phy_cpy, fw_lane_config));
    146             break;
    147         }
    148     }
    149         
    150     return PHYMOD_E_NONE;
    151 }
    152 
    153 
    154 int furia_82212_core_pll_sequencer_restart(const phymod_core_access_t* core, uint32_t flags, phymod_sequencer_operation_t operation)
    155 {
    156     phymod_core_access_t core_cpy;
    157     uint16_t lane_idx = 0;
    158     PHYMOD_MEMSET(&core_cpy, 0, sizeof(phymod_core_access_t));
    159     PHYMOD_MEMCPY(&core_cpy,core, sizeof(phymod_core_access_t));
    160    
    161     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    162         if (core->access.lane_mask & (1 << lane_idx)) {
    163             FURIA_82212_CALL_PHYDRV(core_cpy, lane_idx,
    164                   furia_core_pll_sequencer_restart(&core_cpy, flags, operation));
    165         }
    166     }
    167         
    168     return PHYMOD_E_NONE;
    169 }
    170 
    171 
    172 int furia_82212_phy_polarity_set(const phymod_phy_access_t* phy, const phymod_polarity_t* polarity)
    173 {
    174     phymod_phy_access_t phy_cpy;
    175     uint16_t lane_idx = 0;
    176     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    177     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    178    
    179     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    180         if (phy->access.lane_mask & (1 << lane_idx)) {
    181             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    182                   furia_phy_polarity_set(&phy_cpy, polarity));
    183         }
    184     }
    185         
    186     return PHYMOD_E_NONE;
    187 }
    188 
    189 int furia_82212_phy_polarity_get(const phymod_phy_access_t* phy, phymod_polarity_t* polarity)
    190 {
    191     phymod_phy_access_t phy_cpy;
    192     uint16_t lane_idx = 0;
    193     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    194     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    195    
    196     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    197         if (phy->access.lane_mask & (1 << lane_idx)) {
    198             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    199                   furia_phy_polarity_get(&phy_cpy, polarity));
    200             break;
    201         }
    202     }
    203     return PHYMOD_E_NONE;
    204     
    205 }
    206 
    207 
    208 int furia_82212_phy_tx_set(const phymod_phy_access_t* phy, const phymod_tx_t* tx)
    209 {
    210     phymod_phy_access_t phy_cpy;
    211     uint16_t lane_idx = 0;
    212     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    213     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    214    
    215     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    216         if (phy->access.lane_mask & (1 << lane_idx)) {
    217             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    218                   furia_phy_tx_set(&phy_cpy, tx));
    219         }
    220     }
    221    
    222     return PHYMOD_E_NONE;
    223     
    224 }
    225 
    226 int furia_82212_phy_tx_get(const phymod_phy_access_t* phy, phymod_tx_t* tx)
    227 {
    228     phymod_phy_access_t phy_cpy;
    229     uint16_t lane_idx = 0;
    230     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    231     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    232    
    233     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    234         if (phy->access.lane_mask & (1 << lane_idx)) {
    235             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    236                   furia_phy_tx_get(&phy_cpy, tx));
    237             break;
    238         }
    239     }
    240 
    241     return PHYMOD_E_NONE;
    242 }
    243 
    244 
    245 int furia_82212_phy_rx_set(const phymod_phy_access_t* phy, const phymod_rx_t* rx)
    246 {
    247     phymod_phy_access_t phy_cpy;
    248     uint16_t lane_idx = 0;
    249     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    250     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    251    
    252     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    253         if (phy->access.lane_mask & (1 << lane_idx)) {
    254             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    255                   furia_phy_rx_set(&phy_cpy, rx));
    256         }
    257     }
    258         
    259     return PHYMOD_E_NONE;
    260     
    261 }
    262 
    263 int furia_82212_phy_rx_get(const phymod_phy_access_t* phy, phymod_rx_t* rx)
    264 {
    265     phymod_phy_access_t phy_cpy;
    266     uint16_t lane_idx = 0;
    267     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    268     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    269    
    270     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    271         if (phy->access.lane_mask & (1 << lane_idx)) {
    272             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    273                   furia_phy_rx_get(&phy_cpy, rx));
    274             break;
    275         }
    276     }
    277     
    278     return PHYMOD_E_NONE;
    279     
    280 }
    281 
    282 
    283 int furia_82212_phy_reset_set(const phymod_phy_access_t* phy, const phymod_phy_reset_t* reset)
    284 {
    285     phymod_phy_access_t phy_cpy;
    286     uint16_t lane_idx = 0;
    287     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    288     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    289    
    290     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    291         if (phy->access.lane_mask & (1 << lane_idx)) {
    292             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    293                   furia_phy_reset_set(&phy_cpy, reset));
    294         }
    295     }
    296        
    297     return PHYMOD_E_NONE;
    298     
    299 }
    300 
    301 int furia_82212_phy_reset_get(const phymod_phy_access_t* phy, phymod_phy_reset_t* reset)
    302 {
    303     phymod_phy_access_t phy_cpy;
    304     uint16_t lane_idx = 0;
    305     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    306     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    307    
    308     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    309         if (phy->access.lane_mask & (1 << lane_idx)) {
    310             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    311                   furia_phy_reset_get(&phy_cpy, reset));
    312             break;
    313         }
    314     }
    315     return PHYMOD_E_NONE;
    316     
    317 }
    318 
    319 
    320 int furia_82212_phy_power_set(const phymod_phy_access_t* phy, const phymod_phy_power_t* power)
    321 {
    322     phymod_phy_access_t phy_cpy;
    323     uint16_t lane_idx = 0;
    324     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    325     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    326    
    327     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    328         if (phy->access.lane_mask & (1 << lane_idx)) {
    329             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    330                   furia_phy_power_set(&phy_cpy, power));
    331         }
    332     }
    333        
    334     return PHYMOD_E_NONE;
    335     
    336 }
    337 
    338 int furia_82212_phy_power_get(const phymod_phy_access_t* phy, phymod_phy_power_t* power)
    339 {
    340     phymod_phy_access_t phy_cpy;
    341     uint16_t lane_idx = 0;
    342     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    343     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    344    
    345     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    346         if (phy->access.lane_mask & (1 << lane_idx)) {
    347             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    348                   furia_phy_power_get(&phy_cpy, power));
    349             break;
    350         }
    351     }
    352         
    353     return PHYMOD_E_NONE;
    354     
    355 }
    356 
    357 
    358 int furia_82212_phy_tx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t tx_control)
    359 {
    360     phymod_phy_access_t phy_cpy;
    361     uint16_t lane_idx = 0;
    362     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    363     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    364    
    365     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    366         if (phy->access.lane_mask & (1 << lane_idx)) {
    367             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    368                   furia_phy_tx_lane_control_set(&phy_cpy, tx_control));
    369         }
    370     }
    371         
    372     return PHYMOD_E_NONE;
    373     
    374 }
    375 
    376 int furia_82212_phy_tx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_tx_lane_control_t* tx_control)
    377 {
    378     phymod_phy_access_t phy_cpy;
    379     uint16_t lane_idx = 0;
    380     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    381     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    382    
    383     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    384         if (phy->access.lane_mask & (1 << lane_idx)) {
    385             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    386                   furia_phy_tx_lane_control_get(&phy_cpy, tx_control));
    387             break;
    388         }
    389     }
    390        
    391     return PHYMOD_E_NONE;
    392     
    393 }
    394 
    395 
    396 int furia_82212_phy_rx_lane_control_set(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t rx_control)
    397 {
    398     phymod_phy_access_t phy_cpy;
    399     uint16_t lane_idx = 0;
    400     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    401     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    402    
    403     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    404         if (phy->access.lane_mask & (1 << lane_idx)) {
    405             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    406                   furia_phy_rx_lane_control_set(&phy_cpy, rx_control));
    407         }
    408     }
    409        
    410     return PHYMOD_E_NONE;
    411     
    412 }
    413 
    414 int furia_82212_phy_rx_lane_control_get(const phymod_phy_access_t* phy, phymod_phy_rx_lane_control_t* rx_control)
    415 {
    416     phymod_phy_access_t phy_cpy;
    417     uint16_t lane_idx = 0;
    418     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    419     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    420    
    421     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    422         if (phy->access.lane_mask & (1 << lane_idx)) {
    423             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    424                   furia_phy_rx_lane_control_get(&phy_cpy, rx_control));
    425             break;
    426         }
    427     }
    428        
    429     return PHYMOD_E_NONE;
    430     
    431 }
    432 
    433 int furia_82212_phy_fec_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
    434 {
    435     phymod_phy_access_t phy_cpy;
    436     uint16_t lane_idx = 0;
    437     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    438     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    439    
    440     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    441         if (phy->access.lane_mask & (1 << lane_idx)) {
    442             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    443                   furia_phy_fec_enable_set(&phy_cpy, enable));
    444         }
    445     }
    446        
    447     return PHYMOD_E_NONE;
    448        
    449 }
    450 
    451 int furia_82212_phy_fec_enable_get(const phymod_phy_access_t* phy, uint32_t* enable)
    452 {
    453     phymod_phy_access_t phy_cpy;
    454     uint16_t lane_idx = 0;
    455     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    456     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    457    
    458     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    459         if (phy->access.lane_mask & (1 << lane_idx)) {
    460             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    461                   furia_phy_fec_enable_get(&phy_cpy, enable));
    462             break;
    463         }
    464     }
    465        
    466     return PHYMOD_E_NONE;
    467     
    468 }
    469 
    470 
    471 int furia_82212_phy_interface_config_set(const phymod_phy_access_t* phy, uint32_t flags, const phymod_phy_inf_config_t* config)
    472 {
    473     phymod_phy_access_t phy_cpy;
    474     uint16_t lane_idx = 0, die_idx = 0;
    475     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    476     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    477     
    478     if (phy->access.lane_mask == FURIA_82212_BCAST_LANEMASK) {
    479         for (die_idx = 0; die_idx < FURIA_82212_MAX_DIE; die_idx ++) {
    480             phy_cpy.access.addr |= die_idx;
    481             /* Broadcast to Die 0 and 1*/
    482             phy_cpy.access.lane_mask = 0xFFF;
    483             PHYMOD_IF_ERR_RETURN(
    484                   furia_phy_interface_config_set(&phy_cpy, flags, config));
    485         }
    486     } else {
    487         for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    488             if (phy->access.lane_mask & (1 << lane_idx)) {
    489                 FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    490                       furia_phy_interface_config_set(&phy_cpy, flags, config));
    491            }
    492         }
    493     }
    494     return PHYMOD_E_NONE;
    495     
    496 }
    497 
    498 int furia_82212_phy_interface_config_get(const phymod_phy_access_t* phy, uint32_t flags, phymod_ref_clk_t ref_clock, phymod_phy_inf_config_t* config)
    499 {
    500     phymod_phy_access_t phy_cpy;
    501     uint16_t lane_idx = 0;
    502     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    503     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    504    
    505     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    506         if (phy->access.lane_mask & (1 << lane_idx)) {
    507             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    508                   furia_phy_interface_config_get(&phy_cpy, flags, ref_clock, config));
    509         }
    510     }
    511         
    512     return PHYMOD_E_NONE;
    513     
    514 }
    515 
    516 
    517 int furia_82212_phy_cl72_set(const phymod_phy_access_t* phy, uint32_t cl72_en)
    518 {
    519     phymod_phy_access_t phy_cpy;
    520     uint16_t lane_idx = 0;
    521     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    522     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    523    
    524     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    525         if (phy->access.lane_mask & (1 << lane_idx)) {
    526             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    527                   furia_phy_cl72_set(&phy_cpy, cl72_en));
    528         }
    529     }
    530     return PHYMOD_E_NONE;
    531     
    532 }
    533 
    534 int furia_82212_phy_cl72_get(const phymod_phy_access_t* phy, uint32_t* cl72_en)
    535 {
    536     phymod_phy_access_t phy_cpy;
    537     uint16_t lane_idx = 0;
    538     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    539     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    540    
    541     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    542         if (phy->access.lane_mask & (1 << lane_idx)) {
    543             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    544                   furia_phy_cl72_get(&phy_cpy, cl72_en));
    545             break;
    546         }
    547     }
    548     return PHYMOD_E_NONE;
    549     
    550 }
    551 
    552 
    553 int furia_82212_phy_cl72_status_get(const phymod_phy_access_t* phy, phymod_cl72_status_t* status)
    554 {
    555     phymod_phy_access_t phy_cpy;
    556     uint16_t lane_idx = 0;
    557     phymod_cl72_status_t sts;
    558     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    559     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    560     status->locked = 0xFFFF; 
    561 
    562     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    563         if (phy->access.lane_mask & (1 << lane_idx)) {
    564             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    565                   furia_phy_cl72_status_get(&phy_cpy, &sts));
    566             status->locked &= sts.locked; 
    567         }
    568     }
    569        
    570     return PHYMOD_E_NONE;
    571     
    572 }
    573 
    574 
    575 int furia_82212_phy_autoneg_ability_set(const phymod_phy_access_t* phy, const phymod_autoneg_ability_t* an_ability_set_type)
    576 {
    577         
    578     return PHYMOD_E_NONE;
    579     
    580 }
    581 
    582 int furia_82212_phy_autoneg_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
    583 {
    584     return PHYMOD_E_NONE;
    585     
    586 }
    587 
    588 
    589 int furia_82212_phy_autoneg_remote_ability_get(const phymod_phy_access_t* phy, phymod_autoneg_ability_t* an_ability_get_type)
    590 {
    591     return PHYMOD_E_NONE;
    592     
    593 }
    594 
    595 
    596 int furia_82212_phy_autoneg_set(const phymod_phy_access_t* phy, const phymod_autoneg_control_t* an)
    597 {
    598     return PHYMOD_E_NONE;
    599     
    600 }
    601 
    602 int furia_82212_phy_autoneg_get(const phymod_phy_access_t* phy, phymod_autoneg_control_t* an, uint32_t* an_done)
    603 {
    604     return PHYMOD_E_NONE;
    605     
    606 }
    607 
    608 
    609 int furia_82212_core_init(const phymod_core_access_t* core, const phymod_core_init_config_t* init_config, const phymod_core_status_t* core_status)
    610 {
    611     phymod_core_access_t core_cpy;
    612     uint16_t die_idx = 0;
    613     PHYMOD_MEMSET(&core_cpy, 0, sizeof(phymod_core_access_t));
    614     PHYMOD_MEMCPY(&core_cpy, core, sizeof(phymod_core_access_t));
    615    
    616     core_cpy.access.addr &= (~1);
    617     for (die_idx = 0; die_idx < FURIA_82212_MAX_DIE; die_idx ++) {
    618         core_cpy.access.addr |= die_idx;
    619         PHYMOD_IF_ERR_RETURN(furia_core_init(&core_cpy, init_config, core_status));
    620     }
    621     return PHYMOD_E_NONE;
    622     
    623 }
    624 
    625 
    626 int furia_82212_phy_init(const phymod_phy_access_t* phy, const phymod_phy_init_config_t* init_config)
    627 {
    628     phymod_phy_access_t phy_cpy;
    629     uint16_t lane_idx = 0;
    630     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    631     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    632    
    633     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    634         if (phy->access.lane_mask & (1 << lane_idx)) {
    635             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    636                   furia_phy_init(&phy_cpy, init_config));
    637         }
    638     }
    639 
    640     return PHYMOD_E_NONE;
    641     
    642 }
    643 
    644 
    645 int furia_82212_phy_loopback_set(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t enable)
    646 {
    647         
    648     return PHYMOD_E_NONE;
    649     
    650 }
    651 
    652 int furia_82212_phy_loopback_get(const phymod_phy_access_t* phy, phymod_loopback_mode_t loopback, uint32_t* enable)
    653 {
    654     *enable = 0;
    655         
    656     return PHYMOD_E_NONE;
    657     
    658 }
    659 
    660 
    661 int furia_82212_phy_rx_pmd_locked_get(const phymod_phy_access_t* phy, uint32_t* rx_pmd_locked)
    662 {
    663     phymod_phy_access_t phy_cpy;
    664     uint16_t lane_idx = 0;
    665     uint32_t lock = 0xFFFF;
    666     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    667     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    668    
    669     *rx_pmd_locked = 0xFFFF;
    670     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    671         if (phy->access.lane_mask & (1 << lane_idx)) {
    672             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    673                   furia_phy_rx_pmd_locked_get(&phy_cpy, &lock));
    674             *rx_pmd_locked &= lock;
    675         }
    676     }
    677    
    678     return PHYMOD_E_NONE;
    679     
    680 }
    681 
    682 
    683 int furia_82212_phy_link_status_get(const phymod_phy_access_t* phy, uint32_t* link_status)
    684 {
    685     phymod_phy_access_t phy_cpy;
    686     uint16_t lane_idx = 0;
    687     uint32_t status = 0xFFFF;
    688     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    689     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    690    
    691     *link_status = 0xFFFF;
    692     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    693         if (phy->access.lane_mask & (1 << lane_idx)) {
    694             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    695                   furia_phy_link_status_get(&phy_cpy, &status));
    696             *link_status &= status;
    697         }
    698     }
    699        
    700     return PHYMOD_E_NONE;
    701     
    702 }
    703 
    704 
    705 int furia_82212_phy_status_dump(const phymod_phy_access_t* phy)
    706 {
    707     phymod_phy_access_t phy_cpy;
    708     uint16_t lane_idx = 0;
    709     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    710     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    711    
    712     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    713         if (phy->access.lane_mask & (1 << lane_idx)) {
    714             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    715                   furia_phy_status_dump(&phy_cpy));
    716         }
    717     }
    718         
    719     return PHYMOD_E_NONE;
    720     
    721 }
    722 
    723 
    724 int furia_82212_phy_reg_read(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t* val)
    725 {
    726     phymod_phy_access_t phy_cpy;
    727     uint16_t lane_idx = 0;
    728     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    729     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    730    
    731     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    732         if (phy->access.lane_mask & (1 << lane_idx)) {
    733             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    734                 furia_phy_reg_read(&phy_cpy, reg_addr, val));
    735         }
    736     }
    737 
    738     return PHYMOD_E_NONE;
    739     
    740 }
    741 
    742 
    743 int furia_82212_phy_reg_write(const phymod_phy_access_t* phy, uint32_t reg_addr, uint32_t val)
    744 {
    745     phymod_phy_access_t phy_cpy;
    746     uint16_t lane_idx = 0;
    747     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    748     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    749    
    750     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    751         if (phy->access.lane_mask & (1 << lane_idx)) {
    752             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    753                   furia_phy_reg_write(&phy_cpy, reg_addr, val));
    754         }
    755     }
    756    
    757     return PHYMOD_E_NONE;
    758     
    759 }
    760 
    761 
    762 int furia_82212_phy_lane_cross_switch_map_set(const phymod_phy_access_t* phy, const uint32_t* tx_array)
    763 {
    764     phymod_phy_access_t phy_cpy;
    765     uint16_t lane_idx = 0;
    766     uint16_t die_id = 0;
    767     uint32_t tx_array_conv[FURIA_82212_MAX_LANE];/*12 element type array*/
    768     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    769     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    770 
    771     die_id = ( tx_array[6] ) & ( 1 ) ;
    772 
    773     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    774         FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    775               furia_phy_lane_cross_switch_map_get(&phy_cpy, (uint32_t*)&tx_array_conv));/*get 12 element array*/
    776     }
    777 
    778     /*add array, to higher 7-12 elements for die id 1*/
    779     /*add array, to lower 1-6 elements for die id 0*/
    780     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_DIE_LANE; lane_idx ++) {
    781         tx_array_conv[lane_idx + ( 6 * die_id )] = tx_array[lane_idx] ;
    782     }
    783 
    784     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    785         FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    786               furia_phy_lane_cross_switch_map_set(&phy_cpy, tx_array_conv));
    787     }
    788  
    789     return PHYMOD_E_NONE;
    790     
    791 }
    792 
    793 int furia_82212_phy_lane_cross_switch_map_get(const phymod_phy_access_t* phy, uint32_t* tx_array)
    794 {
    795     phymod_phy_access_t phy_cpy;
    796     uint16_t lane_idx = 0;
    797     uint16_t die_id = 0;
    798     uint32_t copy_tx_array[FURIA_82212_MAX_LANE];/*12 element type array*/
    799     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    800     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    801 
    802     die_id = ( tx_array[6] ) & ( 1 ) ;/*die select*/
    803     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    804         FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    805               furia_phy_lane_cross_switch_map_get(&phy_cpy, (uint32_t*)&copy_tx_array));
    806     }
    807     /*shift array, convert 12 to 8 elements for glue layer*/
    808     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_DIE_LANE; lane_idx ++) {
    809                     tx_array[lane_idx]= copy_tx_array[ lane_idx + (6*die_id) ] ;
    810     }
    811  
    812     return PHYMOD_E_NONE;
    813     
    814 }
    815 
    816 
    817 int furia_82212_phy_intr_enable_set(const phymod_phy_access_t* phy, uint32_t enable)
    818 {
    819     phymod_phy_access_t phy_cpy;
    820     uint16_t lane_idx = 0;
    821     uint16_t prev_die = 0xF;
    822     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    823     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    824    
    825     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    826         if (phy->access.lane_mask & (1 << lane_idx)) {
    827             phy_cpy.access.addr &= ~(1);
    828             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
    829             if (FURIA_82212_GET_DIE_NO(lane_idx) == prev_die) {
    830                 continue;
    831             }
    832             PHYMOD_DEBUG_VERBOSE(("INTR enable Set Addr:%x\n",phy_cpy.access.addr)); 
    833             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    834                   furia_phy_intr_enable_set(&phy_cpy, enable));
    835             prev_die = FURIA_82212_GET_DIE_NO(lane_idx);
    836         }
    837     }
    838         
    839     return PHYMOD_E_NONE;
    840     
    841 }
    842 
    843 int furia_82212_phy_intr_enable_get(const phymod_phy_access_t* phy, uint32_t * enable)
    844 {
    845     phymod_phy_access_t phy_cpy;
    846     uint16_t lane_idx = 0;
    847     uint16_t prev_die = 0xF;
    848     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    849     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    850    
    851     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    852         if (phy->access.lane_mask & (1 << lane_idx)) {
    853             phy_cpy.access.addr &= ~(1);
    854             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
    855             if (FURIA_82212_GET_DIE_NO(lane_idx) == prev_die) {
    856                 continue;
    857             }
    858             PHYMOD_DEBUG_VERBOSE((
    859               "INTR enable Get Addr:%x\n",phy_cpy.access.addr)); 
    860             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    861                   furia_phy_intr_enable_get(&phy_cpy, enable));
    862             prev_die = FURIA_82212_GET_DIE_NO(lane_idx);
    863         }
    864     }
    865         
    866     return PHYMOD_E_NONE;
    867     
    868 }
    869 
    870 
    871 int furia_82212_phy_intr_status_get(const phymod_phy_access_t* phy, uint32_t * intr_status)
    872 {
    873     phymod_phy_access_t phy_cpy;
    874     uint16_t lane_idx = 0;
    875     uint16_t prev_die = 0xF;
    876     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    877     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    878    
    879     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    880         if (phy->access.lane_mask & (1 << lane_idx)) {
    881             phy_cpy.access.addr &= ~(1);
    882             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
    883             if (FURIA_82212_GET_DIE_NO(lane_idx) == prev_die) {
    884                 continue;
    885             }
    886             PHYMOD_DEBUG_VERBOSE((
    887              "INTR STS Get Addr:%x\n",phy_cpy.access.addr)); 
    888             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    889                   furia_phy_intr_status_get(&phy_cpy, intr_status));
    890             prev_die = FURIA_82212_GET_DIE_NO(lane_idx);
    891         }
    892     }
    893         
    894     return PHYMOD_E_NONE;
    895     
    896 }
    897 
    898 
    899 int furia_82212_phy_intr_status_clear(const phymod_phy_access_t* phy, uint32_t intr_type)
    900 {
    901     phymod_phy_access_t phy_cpy;
    902     uint16_t lane_idx = 0;
    903     uint16_t prev_die = 0xF;
    904     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    905     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    906    
    907     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    908         if (phy->access.lane_mask & (1 << lane_idx)) {
    909             phy_cpy.access.addr &= ~(1);
    910             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
    911             if (FURIA_82212_GET_DIE_NO(lane_idx) == prev_die) {
    912                 continue;
    913             }
    914             PHYMOD_DEBUG_VERBOSE((
    915              "INTR STS clear:%x\n",phy_cpy.access.addr)); 
    916             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    917                   furia_phy_intr_status_clear(&phy_cpy, intr_type));
    918             prev_die = FURIA_82212_GET_DIE_NO(lane_idx);
    919         }
    920     }
    921        
    922     return PHYMOD_E_NONE;
    923     
    924 }
    925 
    926 
    927 int furia_82212_phy_i2c_read(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, uint8_t* data)
    928 {
    929     phymod_phy_access_t phy_cpy;
    930     uint16_t lane_idx = 0;
    931     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    932     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    933    
    934     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    935         if (phy->access.lane_mask & (1 << lane_idx)) {
    936             phy_cpy.access.addr &= ~(1);
    937             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
    938             PHYMOD_DEBUG_VERBOSE((
    939                "I2c read:%x\n",phy_cpy.access.addr)); 
    940             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    941                   furia_phy_i2c_read(&phy_cpy, flags, addr, offset, size, data));
    942             break;
    943         }
    944     }
    945    
    946     return PHYMOD_E_NONE;
    947     
    948 }
    949 
    950 
    951 int furia_82212_phy_i2c_write(const phymod_phy_access_t* phy, uint32_t flags, uint32_t addr, uint32_t offset, uint32_t size, const uint8_t* data)
    952 {
    953     phymod_phy_access_t phy_cpy;
    954     uint16_t lane_idx = 0;
    955     uint16_t prev_die = 0xF;
    956     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    957     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    958    
    959     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    960         if (phy->access.lane_mask & (1 << lane_idx)) {
    961             phy_cpy.access.addr &= ~(1);
    962             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
    963             if (FURIA_82212_GET_DIE_NO(lane_idx) == prev_die) {
    964                 continue;
    965             }
    966             PHYMOD_DEBUG_VERBOSE((
    967               "I2c write:%x\n",phy_cpy.access.addr)); 
    968             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    969                   furia_phy_i2c_write(&phy_cpy, flags, addr, offset, size, data));
    970             prev_die = FURIA_82212_GET_DIE_NO(lane_idx);
    971         }
    972     }
    973         
    974     return PHYMOD_E_NONE;
    975     
    976 }
    977 
    978 
    979 int furia_82212_phy_gpio_config_set(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t gpio_mode)
    980 {
    981     phymod_phy_access_t phy_cpy;
    982     uint16_t lane_idx = 0;
    983     uint16_t prev_die = 0xF;
    984     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
    985     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
    986    
    987     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
    988         if (phy->access.lane_mask & (1 << lane_idx)) {
    989             phy_cpy.access.addr &= ~(1);
    990             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
    991             if (FURIA_82212_GET_DIE_NO(lane_idx) == prev_die) {
    992                 continue;
    993             }
    994             PHYMOD_DEBUG_VERBOSE((
    995               "GPIO config set:%x\n",phy_cpy.access.addr)); 
    996             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
    997                   furia_phy_gpio_config_set(&phy_cpy, pin_no, gpio_mode));
    998             prev_die = FURIA_82212_GET_DIE_NO(lane_idx);
    999         }
   1000     }
   1001        
   1002     return PHYMOD_E_NONE;
   1003     
   1004 }
   1005 
   1006 int furia_82212_phy_gpio_config_get(const phymod_phy_access_t* phy, int pin_no, phymod_gpio_mode_t* gpio_mode)
   1007 {
   1008     phymod_phy_access_t phy_cpy;
   1009     uint16_t lane_idx = 0;
   1010     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
   1011     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
   1012    
   1013     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
   1014         if (phy->access.lane_mask & (1 << lane_idx)) {
   1015             phy_cpy.access.addr &= ~(1);
   1016             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
   1017             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
   1018                   furia_phy_gpio_config_get(&phy_cpy, pin_no, gpio_mode));
   1019             break;
   1020         }
   1021     }
   1022        
   1023     return PHYMOD_E_NONE;
   1024     
   1025 }
   1026 
   1027 
   1028 int furia_82212_phy_gpio_pin_value_set(const phymod_phy_access_t* phy, int pin_no, int value)
   1029 {
   1030     phymod_phy_access_t phy_cpy;
   1031     uint16_t lane_idx = 0;
   1032     uint16_t prev_die = 0xF;
   1033     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
   1034     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
   1035    
   1036     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
   1037         if (phy->access.lane_mask & (1 << lane_idx)) {
   1038             phy_cpy.access.addr &= ~(1);
   1039             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
   1040             if (FURIA_82212_GET_DIE_NO(lane_idx) == prev_die) {
   1041                 continue;
   1042             }
   1043             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
   1044                   furia_phy_gpio_pin_value_set(&phy_cpy, pin_no, value));
   1045             prev_die = FURIA_82212_GET_DIE_NO(lane_idx);
   1046         }
   1047     }
   1048        
   1049     return PHYMOD_E_NONE;
   1050     
   1051 }
   1052 
   1053 int furia_82212_phy_gpio_pin_value_get(const phymod_phy_access_t* phy, int pin_no, int* value)
   1054 {
   1055     phymod_phy_access_t phy_cpy;
   1056     uint16_t lane_idx = 0;
   1057     PHYMOD_MEMSET(&phy_cpy, 0, sizeof(phymod_phy_access_t));
   1058     PHYMOD_MEMCPY(&phy_cpy, phy, sizeof(phymod_phy_access_t));
   1059    
   1060     for (lane_idx = 0; lane_idx < FURIA_82212_MAX_LANE; lane_idx ++) {
   1061         if (phy->access.lane_mask & (1 << lane_idx)) {
   1062             phy_cpy.access.addr &= ~(1);
   1063             phy_cpy.access.addr |= FURIA_82212_GET_DIE_NO(lane_idx);
   1064             FURIA_82212_CALL_PHYDRV(phy_cpy, lane_idx,
   1065                   furia_phy_gpio_pin_value_get(&phy_cpy, pin_no, value));
   1066             break;
   1067         }
   1068     }
   1069 
   1070     return PHYMOD_E_NONE;
   1071     
   1072 }
   1073 
   1074 int furia_82212_phy_op_mode_get(const phymod_phy_access_t* phy, phymod_operation_mode_t* op_mode)
   1075 {
   1076     return PHYMOD_E_UNAVAIL;
   1077 }
   1078 
   1079 #endif /* PHYMOD_FURIA_SUPPORT */