iPXE
Functions
mlx_pci_gw.c File Reference
#include "../../include/public/mlx_pci_gw.h"
#include "../../include/public/mlx_bail.h"
#include "../../include/public/mlx_pci.h"
#include "../../include/public/mlx_logging.h"

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
static mlx_status mlx_pci_gw_check_capability_id (IN mlx_utils *utils, IN mlx_uint8 cap_pointer, OUT mlx_boolean *bool)
static mlx_status mlx_pci_gw_get_ownership (IN mlx_utils *utils)
static mlx_status mlx_pci_gw_free_ownership (IN mlx_utils *utils)
static mlx_status mlx_pci_gw_set_space (IN mlx_utils *utils, IN mlx_pci_gw_space space)
static mlx_status mlx_pci_gw_wait_for_flag_value (IN mlx_utils *utils, IN mlx_boolean value)
static mlx_status mlx_pci_gw_search_capability (IN mlx_utils *utils, OUT mlx_uint32 *cap_offset)
mlx_status mlx_pci_gw_init (IN mlx_utils *utils)
mlx_status mlx_pci_gw_teardown (IN mlx_utils *utils)
mlx_status mlx_pci_gw_read (IN mlx_utils *utils, IN mlx_pci_gw_space space, IN mlx_uint32 address, OUT mlx_pci_gw_buffer *buffer)
mlx_status mlx_pci_gw_write (IN mlx_utils *utils, IN mlx_pci_gw_space space, IN mlx_uint32 address, IN mlx_pci_gw_buffer buffer)

Function Documentation

FILE_LICENCE ( GPL2_OR_LATER  )
static mlx_status mlx_pci_gw_check_capability_id ( IN mlx_utils utils,
IN mlx_uint8  cap_pointer,
OUT mlx_boolean bool 
) [static]

Definition at line 32 of file mlx_pci_gw.c.

References MLX_CHECK_STATUS, mlx_pci_read(), MLX_SUCCESS, MlxPciWidthUint8, offset, PCI_GW_CAPABILITY_ID, PCI_GW_CAPABILITY_ID_OFFSET, and status.

Referenced by mlx_pci_gw_search_capability().

{
        mlx_status              status = MLX_SUCCESS;
        mlx_uint8               offset = cap_pointer + PCI_GW_CAPABILITY_ID_OFFSET;
        mlx_uint8               id = 0;
        status = mlx_pci_read(utils, MlxPciWidthUint8, offset,
                                1, &id);
        MLX_CHECK_STATUS(utils, status, read_err,"failed to read capability id");
        *bool = ( id == PCI_GW_CAPABILITY_ID );
read_err:
        return status;
}
static mlx_status mlx_pci_gw_get_ownership ( IN mlx_utils utils) [static]

Definition at line 51 of file mlx_pci_gw.c.

References MLX_CHECK_STATUS, MLX_FAILED, mlx_pci_read(), mlx_pci_write(), MLX_SUCCESS, mlx_utils_delay_in_us(), MlxPciWidthUint32, PCI_GW_CAPABILITY_COUNTER_OFFSET, PCI_GW_CAPABILITY_SEMAPHORE_OFFSET, PCI_GW_GET_OWNERSHIP_TRIES, PCI_GW_SEMPHORE_TRIES, and status.

Referenced by mlx_pci_gw_init(), mlx_pci_gw_read(), and mlx_pci_gw_write().

{
        mlx_status                      status = MLX_SUCCESS;
        mlx_uint32                      cap_offset = utils->pci_gw.pci_cmd_offset;
        mlx_uint32                      semaphore = 0;
        mlx_uint32                      counter = 0;
        mlx_uint32                      get_semaphore_try = 0;
        mlx_uint32                      get_ownership_try = 0;

        for( ; get_ownership_try < PCI_GW_GET_OWNERSHIP_TRIES; get_ownership_try ++){
                for( ; get_semaphore_try <= PCI_GW_SEMPHORE_TRIES ; get_semaphore_try++){
                        status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_SEMAPHORE_OFFSET,
                                        1, &semaphore);
                        MLX_CHECK_STATUS(utils, status, read_err,"failed to read semaphore");
                        if( semaphore == 0 ){
                                break;
                        }
                        mlx_utils_delay_in_us(10);
                }
                if( semaphore != 0 ){
                        status = MLX_FAILED;
                        goto semaphore_err;
                }

                status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_COUNTER_OFFSET,
                                                1, &counter);
                MLX_CHECK_STATUS(utils, status, read_err, "failed to read counter");

                status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_SEMAPHORE_OFFSET,
                                                1, &counter);
                MLX_CHECK_STATUS(utils, status, write_err,"failed to write semaphore");

                status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_SEMAPHORE_OFFSET,
                                                1, &semaphore);
                MLX_CHECK_STATUS(utils, status, read_err,"failed to read semaphore");
                if( counter == semaphore ){
                        break;
                }
        }
        if( counter != semaphore ){
                status = MLX_FAILED;
        }
write_err:
read_err:
semaphore_err:
        return status;
}
static mlx_status mlx_pci_gw_free_ownership ( IN mlx_utils utils) [static]

Definition at line 103 of file mlx_pci_gw.c.

References MLX_CHECK_STATUS, mlx_pci_write(), MLX_SUCCESS, MlxPciWidthUint32, PCI_GW_CAPABILITY_SEMAPHORE_OFFSET, status, and value.

Referenced by mlx_pci_gw_read(), mlx_pci_gw_teardown(), and mlx_pci_gw_write().

{
        mlx_status              status = MLX_SUCCESS;
        mlx_uint32              cap_offset = utils->pci_gw.pci_cmd_offset;
        mlx_uint32              value = 0;

        status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_SEMAPHORE_OFFSET,
                                        1, &value);
        MLX_CHECK_STATUS(utils, status, write_err,"failed to write semaphore");
write_err:
        return status;
}
static mlx_status mlx_pci_gw_set_space ( IN mlx_utils utils,
IN mlx_pci_gw_space  space 
) [static]

Definition at line 120 of file mlx_pci_gw.c.

References MLX_CHECK_STATUS, MLX_FAILED, mlx_pci_read(), mlx_pci_write(), MLX_SUCCESS, MlxPciWidthUint16, MlxPciWidthUint8, PCI_GW_CAPABILITY_SPACE_OFFSET, PCI_GW_CAPABILITY_STATUS_OFFSET, and status.

Referenced by mlx_pci_gw_read(), and mlx_pci_gw_write().

{
        mlx_status              status = MLX_SUCCESS;
        mlx_uint32              cap_offset = utils->pci_gw.pci_cmd_offset;;
        mlx_uint8               space_status = 0;

        /* set nodnic*/
        status = mlx_pci_write(utils, MlxPciWidthUint16, cap_offset + PCI_GW_CAPABILITY_SPACE_OFFSET, 1, &space);
        MLX_CHECK_STATUS(utils, status, read_error,"failed to write capability space");

        status = mlx_pci_read(utils, MlxPciWidthUint8, cap_offset + PCI_GW_CAPABILITY_STATUS_OFFSET, 1, &space_status);
        MLX_CHECK_STATUS(utils, status, read_error,"failed to read capability status");
        if( (space_status & 0x20) == 0){
                status = MLX_FAILED;
                goto space_unsupported;
        }
read_error:
space_unsupported:
        return status;
}
static mlx_status mlx_pci_gw_wait_for_flag_value ( IN mlx_utils utils,
IN mlx_boolean  value 
) [static]

Definition at line 146 of file mlx_pci_gw.c.

References flag, MLX_CHECK_STATUS, MLX_FAILED, mlx_pci_read(), MLX_SUCCESS, mlx_utils_delay_in_us(), MlxPciWidthUint32, PCI_GW_CAPABILITY_FLAG_OFFSET, PCI_GW_READ_FLAG_TRIES, and status.

Referenced by mlx_pci_gw_read(), and mlx_pci_gw_write().

{
        mlx_status              status = MLX_SUCCESS;
        mlx_uint32              try = 0;
        mlx_uint32              cap_offset = utils->pci_gw.pci_cmd_offset;
        mlx_uint32              flag = 0;

        for(; try < PCI_GW_READ_FLAG_TRIES ; try ++ ) {
                status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_FLAG_OFFSET, 1, &flag);
                MLX_CHECK_STATUS(utils, status, read_error, "failed to read capability flag");
                if( ((flag & 0x80000000) != 0) == value ){
                        goto flag_valid;
                }
                mlx_utils_delay_in_us(10);
        }
        status = MLX_FAILED;
flag_valid:
read_error:
        return status;
}
static mlx_status mlx_pci_gw_search_capability ( IN mlx_utils utils,
OUT mlx_uint32 cap_offset 
) [static]

Definition at line 171 of file mlx_pci_gw.c.

References FALSE, MLX_CHECK_STATUS, MLX_INVALID_PARAMETER, MLX_NOT_FOUND, mlx_pci_gw_check_capability_id(), mlx_pci_read(), MLX_SUCCESS, MlxPciWidthUint8, NULL, PCI_GW_CAPABILITY_NEXT_POINTER_OFFSET, PCI_GW_FIRST_CAPABILITY_POINTER_OFFSET, status, and TRUE.

Referenced by mlx_pci_gw_init().

{
        mlx_status              status = MLX_SUCCESS;
        mlx_uint8               cap_pointer = 0;
        mlx_boolean             is_capability = FALSE;

        if( cap_offset == NULL || utils == NULL){
                status = MLX_INVALID_PARAMETER;
                goto bad_param;
        }

        //get first capability pointer
        status = mlx_pci_read(utils, MlxPciWidthUint8, PCI_GW_FIRST_CAPABILITY_POINTER_OFFSET,
                        1, &cap_pointer);
        MLX_CHECK_STATUS(utils, status, read_err,
                        "failed to read capability pointer");

        //search the right capability
        while( cap_pointer != 0 ){
                status = mlx_pci_gw_check_capability_id(utils, cap_pointer, &is_capability);
                MLX_CHECK_STATUS(utils, status, check_err
                                ,"failed to check capability id");

                if( is_capability == TRUE ){
                        *cap_offset = cap_pointer;
                        break;
                }

                status = mlx_pci_read(utils, MlxPciWidthUint8, cap_pointer +
                                PCI_GW_CAPABILITY_NEXT_POINTER_OFFSET ,
                                1, &cap_pointer);
                MLX_CHECK_STATUS(utils, status, read_err,
                                "failed to read capability pointer");
        }
        if( is_capability != TRUE ){
                status = MLX_NOT_FOUND;
        }
check_err:
read_err:
bad_param:
        return status;
}

Definition at line 218 of file mlx_pci_gw.c.

References MLX_CHECK_STATUS, MLX_INVALID_PARAMETER, mlx_pci_gw_get_ownership(), mlx_pci_gw_search_capability(), MLX_SUCCESS, NULL, mlx_pci_gw::pci_cmd_offset, and status.

Referenced by flexboot_nodnic_is_supported(), and init_mlx_utils().

{
        mlx_status              status = MLX_SUCCESS;
        mlx_pci_gw *pci_gw = NULL;

        if( utils == NULL){
                status = MLX_INVALID_PARAMETER;
                goto bad_param;
        }

        pci_gw = &utils->pci_gw;

        status = mlx_pci_gw_search_capability(utils, &pci_gw->pci_cmd_offset);
        MLX_CHECK_STATUS(utils, status, cap_err,
                                        "mlx_pci_gw_search_capability failed");

#if ! defined ( VSEC_DEBUG )
        status = mlx_pci_gw_get_ownership(utils);
        MLX_CHECK_STATUS(utils, status, ownership_err,"failed to get ownership");
ownership_err:
#endif
cap_err:
bad_param:
        return status;
}

Definition at line 247 of file mlx_pci_gw.c.

References mlx_pci_gw_free_ownership(), and MLX_SUCCESS.

Referenced by flexboot_nodnic_is_supported(), free_mlx_utils(), and init_mlx_utils().

{
#if ! defined ( VSEC_DEBUG )
        mlx_pci_gw_free_ownership(utils);
#endif
        return MLX_SUCCESS;
}
mlx_status mlx_pci_gw_read ( IN mlx_utils utils,
IN mlx_pci_gw_space  space,
IN mlx_uint32  address,
OUT mlx_pci_gw_buffer buffer 
)

Definition at line 258 of file mlx_pci_gw.c.

References MLX_CHECK_STATUS, MLX_INVALID_PARAMETER, mlx_pci_gw_free_ownership(), mlx_pci_gw_get_ownership(), mlx_pci_gw_set_space(), mlx_pci_gw_wait_for_flag_value(), mlx_pci_read(), mlx_pci_write(), MLX_SUCCESS, mlx_utils_acquire_lock(), mlx_utils_delay_in_us(), mlx_utils_release_lock(), MlxPciWidthUint32, NULL, mlx_pci_gw::pci_cmd_offset, PCI_GW_CAPABILITY_ADDRESS_OFFSET, PCI_GW_CAPABILITY_DATA_OFFSET, mlx_pci_gw::space, status, and TRUE.

Referenced by flexboot_nodnic_is_supported(), mlx_icmd_get_semaphore(), mlx_icmd_get_status(), mlx_icmd_go(), mlx_icmd_init(), mlx_icmd_read_buffer(), mlx_icmd_set_opcode(), and nodnic_cmd_read().

{
        mlx_status              status = MLX_SUCCESS;
        mlx_pci_gw              *pci_gw = NULL;
        mlx_uint32              cap_offset = 0;

        if (utils == NULL || buffer == NULL || utils->pci_gw.pci_cmd_offset == 0) {
                status = MLX_INVALID_PARAMETER;
                goto bad_param;
        }

        mlx_utils_acquire_lock(utils);

        pci_gw = &utils->pci_gw;
        cap_offset = pci_gw->pci_cmd_offset;

#if ! defined ( VSEC_DEBUG )
        if (pci_gw->space != space) {
                   status = mlx_pci_gw_set_space(utils, space);
                   MLX_CHECK_STATUS(utils, status, space_error,"failed to set space");
                   pci_gw->space = space;
        }
#else
        status = mlx_pci_gw_get_ownership(utils);
        MLX_CHECK_STATUS(utils, status, ownership_err,"failed to get ownership");

        status = mlx_pci_gw_set_space(utils, space);
        MLX_CHECK_STATUS(utils, status, space_error,"failed to set space");
        pci_gw->space = space;
#endif

        status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_ADDRESS_OFFSET, 1, &address);
        MLX_CHECK_STATUS(utils, status, read_error,"failed to write capability address");

#if defined ( DEVICE_CX3 )
        /* WA for PCI issue (race) */
        mlx_utils_delay_in_us ( 10 );
#endif

        status = mlx_pci_gw_wait_for_flag_value(utils, TRUE);
        MLX_CHECK_STATUS(utils, status, read_error, "flag failed to change");

        status = mlx_pci_read(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_DATA_OFFSET, 1, buffer);
        MLX_CHECK_STATUS(utils, status, read_error,"failed to read capability data");

#if defined ( VSEC_DEBUG )
        status = mlx_pci_gw_free_ownership(utils);
        MLX_CHECK_STATUS(utils, status, free_err,
                                                "mlx_pci_gw_free_ownership failed");
free_err:
        mlx_utils_release_lock(utils);
        return status;
#endif
read_error:
space_error:
#if defined ( VSEC_DEBUG )
        mlx_pci_gw_free_ownership(utils);
ownership_err:
#endif
mlx_utils_release_lock(utils);
bad_param:
        return status;
}

Definition at line 328 of file mlx_pci_gw.c.

References FALSE, MLX_CHECK_STATUS, MLX_INVALID_PARAMETER, mlx_pci_gw_free_ownership(), mlx_pci_gw_get_ownership(), mlx_pci_gw_set_space(), mlx_pci_gw_wait_for_flag_value(), mlx_pci_write(), MLX_SUCCESS, mlx_utils_acquire_lock(), mlx_utils_release_lock(), MlxPciWidthUint32, NULL, mlx_pci_gw::pci_cmd_offset, PCI_GW_CAPABILITY_ADDRESS_OFFSET, PCI_GW_CAPABILITY_DATA_OFFSET, PCI_GW_WRITE_FLAG, mlx_pci_gw::space, and status.

Referenced by mlx_icmd_clear_semaphore(), mlx_icmd_get_semaphore(), mlx_icmd_go(), mlx_icmd_set_opcode(), mlx_icmd_write_buffer(), and nodnic_cmd_write().

{
        mlx_status              status = MLX_SUCCESS;
        mlx_pci_gw              *pci_gw = NULL;
        mlx_uint32              cap_offset = 0;
        mlx_uint32              fixed_address = address | PCI_GW_WRITE_FLAG;

        if (utils == NULL || utils->pci_gw.pci_cmd_offset == 0) {
                status = MLX_INVALID_PARAMETER;
                goto bad_param;
        }

        mlx_utils_acquire_lock(utils);

        pci_gw = &utils->pci_gw;
        cap_offset = pci_gw->pci_cmd_offset;

#if ! defined ( VSEC_DEBUG )
        if (pci_gw->space != space) {
                   status = mlx_pci_gw_set_space(utils, space);
                   MLX_CHECK_STATUS(utils, status, space_error,"failed to set space");
                   pci_gw->space = space;
        }
#else
        status = mlx_pci_gw_get_ownership(utils);
        MLX_CHECK_STATUS(utils, status, ownership_err,"failed to get ownership");

        status = mlx_pci_gw_set_space(utils, space);
        MLX_CHECK_STATUS(utils, status, space_error,"failed to set space");
        pci_gw->space = space;
#endif
        status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_DATA_OFFSET, 1, &buffer);
        MLX_CHECK_STATUS(utils, status, read_error,"failed to write capability data");

        status = mlx_pci_write(utils, MlxPciWidthUint32, cap_offset + PCI_GW_CAPABILITY_ADDRESS_OFFSET, 1, &fixed_address);
        MLX_CHECK_STATUS(utils, status, read_error,"failed to write capability address");

        status = mlx_pci_gw_wait_for_flag_value(utils, FALSE);
        MLX_CHECK_STATUS(utils, status, read_error, "flag failed to change");
#if defined ( VSEC_DEBUG )
        status = mlx_pci_gw_free_ownership(utils);
        MLX_CHECK_STATUS(utils, status, free_err,
                                                "mlx_pci_gw_free_ownership failed");
free_err:
mlx_utils_release_lock(utils);
        return status;
#endif
read_error:
space_error:
#if defined ( VSEC_DEBUG )
        mlx_pci_gw_free_ownership(utils);
ownership_err:
#endif
mlx_utils_release_lock(utils);
bad_param:
        return status;
}