/* * MlxPciPriv.c * * Created on: Jan 21, 2015 * Author: maord */ #include #include "../../mlx_utils/include/private/mlx_pci_priv.h" static mlx_status mlx_pci_config_byte( IN mlx_utils *utils, IN mlx_boolean read, IN mlx_uint32 offset, IN OUT mlx_uint8 *buffer ) { mlx_status status = MLX_SUCCESS; if (read) { status = pci_read_config_byte(utils->pci, offset, buffer); }else { status = pci_write_config_byte(utils->pci, offset, *buffer); } return status; } static mlx_status mlx_pci_config_word( IN mlx_utils *utils, IN mlx_boolean read, IN mlx_uint32 offset, IN OUT mlx_uint16 *buffer ) { mlx_status status = MLX_SUCCESS; if (read) { status = pci_read_config_word(utils->pci, offset, buffer); }else { status = pci_write_config_word(utils->pci, offset, *buffer); } return status; } static mlx_status mlx_pci_config_dword( IN mlx_utils *utils, IN mlx_boolean read, IN mlx_uint32 offset, IN OUT mlx_uint32 *buffer ) { mlx_status status = MLX_SUCCESS; if (read) { status = pci_read_config_dword(utils->pci, offset, buffer); }else { status = pci_write_config_dword(utils->pci, offset, *buffer); } return status; } static mlx_status mlx_pci_config( IN mlx_utils *utils, IN mlx_boolean read, IN mlx_pci_width width, IN mlx_uint32 offset, IN mlx_uintn count, IN OUT mlx_void *buffer ) { mlx_status status = MLX_SUCCESS; mlx_uint8 *tmp = (mlx_uint8*)buffer; mlx_uintn iteration = 0; if( width == MlxPciWidthUint64) { width = MlxPciWidthUint32; count = count * 2; } for(;iteration < count ; iteration++) { switch (width){ case MlxPciWidthUint8: status = mlx_pci_config_byte(utils, read , offset++, tmp++); break; case MlxPciWidthUint16: status = mlx_pci_config_word(utils, read , offset, (mlx_uint16*)tmp); tmp += 2; offset += 2; break; case MlxPciWidthUint32: status = mlx_pci_config_dword(utils, read , offset, (mlx_uint32*)tmp); tmp += 4; offset += 4; break; default: status = MLX_INVALID_PARAMETER; } if(status != MLX_SUCCESS) { goto config_error; } } config_error: return status; } mlx_status mlx_pci_init_priv( IN mlx_utils *utils ) { mlx_status status = MLX_SUCCESS; adjust_pci_device ( utils->pci ); #ifdef DEVICE_CX3 utils->config = ioremap ( pci_bar_start ( utils->pci, PCI_BASE_ADDRESS_0), 0x100000 ); #endif return status; } mlx_status mlx_pci_teardown_priv( IN mlx_utils *utils __attribute__ ((unused)) ) { mlx_status status = MLX_SUCCESS; #ifdef DEVICE_CX3 iounmap( utils->config ); #endif return status; } mlx_status mlx_pci_read_priv( IN mlx_utils *utils, IN mlx_pci_width width, IN mlx_uint32 offset, IN mlx_uintn count, OUT mlx_void *buffer ) { mlx_status status = MLX_SUCCESS; status = mlx_pci_config(utils, TRUE, width, offset, count, buffer); return status; } mlx_status mlx_pci_write_priv( IN mlx_utils *utils, IN mlx_pci_width width, IN mlx_uint32 offset, IN mlx_uintn count, IN mlx_void *buffer ) { mlx_status status = MLX_SUCCESS; status = mlx_pci_config(utils, FALSE, width, offset, count, buffer); return status; } mlx_status mlx_pci_mem_read_priv( IN mlx_utils *utils __attribute__ ((unused)), IN mlx_pci_width width __attribute__ ((unused)), IN mlx_uint8 bar_index __attribute__ ((unused)), IN mlx_uint64 offset, IN mlx_uintn count __attribute__ ((unused)), OUT mlx_void *buffer ) { if (buffer == NULL || width != MlxPciWidthUint32) return MLX_INVALID_PARAMETER; *((mlx_uint32 *)buffer) = readl(offset); return MLX_SUCCESS; } mlx_status mlx_pci_mem_write_priv( IN mlx_utils *utils __attribute__ ((unused)), IN mlx_pci_width width __attribute__ ((unused)), IN mlx_uint8 bar_index __attribute__ ((unused)), IN mlx_uint64 offset, IN mlx_uintn count __attribute__ ((unused)), IN mlx_void *buffer ) { if (buffer == NULL || width != MlxPciWidthUint32) return MLX_INVALID_PARAMETER; barrier(); writel(*((mlx_uint32 *)buffer), offset); return MLX_SUCCESS; }