mirror of
https://github.com/xcat2/xNBA.git
synced 2024-12-14 15:21:32 +00:00
Command interface now reasonably friendly.
This commit is contained in:
parent
bf9bd93856
commit
791f992657
@ -16,24 +16,6 @@
|
||||
#define ARBEL_OPCODE_RECV_ERROR 0xfe
|
||||
#define ARBEL_OPCODE_SEND_ERROR 0xff
|
||||
|
||||
/*
|
||||
* HCA commands
|
||||
*
|
||||
*/
|
||||
|
||||
#define ARBEL_HCR_BASE 0x80680
|
||||
#define ARBEL_HCR_REG(x) ( ARBEL_HCR_BASE + 4 * (x) )
|
||||
#define ARBEL_HCR_MAX_WAIT_MS 2000
|
||||
|
||||
#define ARBEL_HCR_OPCODE_MASK 0x0000ffffUL
|
||||
#define ARBEL_HCR_IN_IMMEDIATE 0x00010000UL
|
||||
#define ARBEL_HCR_IN_MAILBOX 0x00020000UL
|
||||
#define ARBEL_HCR_OUT_IMMEDIATE 0x00040000UL
|
||||
#define ARBEL_HCR_OUT_MAILBOX 0x00080000UL
|
||||
|
||||
#define ARBEL_HCR_OP_SW2HW_CQ ( 0x0016 | ARBEL_HCR_IN_MAILBOX )
|
||||
#define ARBEL_HCR_OP_NOP ( 0x0031 )
|
||||
|
||||
/*
|
||||
* Wrapper structures for hardware datatypes
|
||||
*
|
||||
@ -45,6 +27,7 @@ struct MLX_DECLARE_STRUCT ( arbelprm_completion_with_error );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_cq_ci_db_record );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_hca_command_register );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_qp_db_record );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_query_dev_lim );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_recv_wqe_segment_next );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_send_doorbell );
|
||||
struct MLX_DECLARE_STRUCT ( arbelprm_ud_address_vector );
|
||||
@ -165,4 +148,46 @@ struct arbel {
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* HCA commands
|
||||
*
|
||||
*/
|
||||
|
||||
#define ARBEL_HCR_QUERY_DEV_LIM 0x0003
|
||||
|
||||
#define ARBEL_HCR_BASE 0x80680
|
||||
#define ARBEL_HCR_REG(x) ( ARBEL_HCR_BASE + 4 * (x) )
|
||||
#define ARBEL_HCR_MAX_WAIT_MS 2000
|
||||
|
||||
/* HCA command is split into
|
||||
*
|
||||
* bits 11:0 Opcode
|
||||
* bit 12 Input uses mailbox
|
||||
* bit 13 Output uses mailbox
|
||||
* bits 22:14 Input parameter length (in dwords)
|
||||
* bits 31:23 Output parameter length (in dwords)
|
||||
*
|
||||
* Encoding the information in this way allows us to cut out several
|
||||
* parameters to the arbel_command() call.
|
||||
*/
|
||||
#define ARBEL_HCR_IN_MBOX 0x00001000UL
|
||||
#define ARBEL_HCR_OUT_MBOX 0x00002000UL
|
||||
#define ARBEL_HCR_OPCODE( _command ) ( (_command) & 0xfff )
|
||||
#define ARBEL_HCR_IN_LEN( _command ) ( ( (_command) >> 12 ) & 0x7fc )
|
||||
#define ARBEL_HCR_OUT_LEN( _command ) ( ( (_command) >> 21 ) & 0x7fc )
|
||||
|
||||
/** Build HCR command from component parts */
|
||||
#define ARBEL_HCR_CMD( _opcode, _in_mbox, _in_len, _out_mbox, _out_len ) \
|
||||
( (_opcode) | \
|
||||
( (_in_mbox) ? ARBEL_HCR_IN_MBOX : 0 ) | \
|
||||
( ( (_in_len) / 4 ) << 14 ) | \
|
||||
( (_out_mbox) ? ARBEL_HCR_OUT_MBOX : 0 ) | \
|
||||
( ( (_out_len) / 4 ) << 23 ) )
|
||||
|
||||
#define ARBEL_HCR_IN_CMD( _opcode, _in_mbox, _in_len ) \
|
||||
ARBEL_HCR_CMD ( _opcode, _in_mbox, _in_len, 0, 0 )
|
||||
|
||||
#define ARBEL_HCR_OUT_CMD( _opcode, _out_mbox, _out_len ) \
|
||||
ARBEL_HCR_CMD ( _opcode, 0, 0, _out_mbox, _out_len )
|
||||
|
||||
#endif /* _ARBEL_H */
|
||||
|
@ -268,14 +268,21 @@ static struct net_device_operations mlx_operations = {
|
||||
.irq = mlx_irq,
|
||||
};
|
||||
|
||||
/***************************************************************************
|
||||
*
|
||||
* HCA commands
|
||||
*
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
/**
|
||||
* Wait for Arbel command completion
|
||||
*
|
||||
* @v arbel Arbel device
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int arbel_command_wait ( struct arbel *arbel,
|
||||
struct arbelprm_hca_command_register *hcr ) {
|
||||
static int arbel_cmd_wait ( struct arbel *arbel,
|
||||
struct arbelprm_hca_command_register *hcr ) {
|
||||
unsigned int wait;
|
||||
|
||||
for ( wait = ARBEL_HCR_MAX_WAIT_MS ; wait ; wait-- ) {
|
||||
@ -292,45 +299,54 @@ static int arbel_command_wait ( struct arbel *arbel,
|
||||
* Issue HCA command
|
||||
*
|
||||
* @v arbel Arbel device
|
||||
* @v op_fl Opcode (plus implied flags)
|
||||
* @v command Command opcode, flags and input/output lengths
|
||||
* @v op_mod Opcode modifier (0 if no modifier applicable)
|
||||
* @v in_param Input parameter
|
||||
* @v in_param_len Input parameter length
|
||||
* @v in Input parameters
|
||||
* @v in_mod Input modifier (0 if no modifier applicable)
|
||||
* @v out_param Output parameter
|
||||
* @v out Output parameters
|
||||
* @ret rc Return status code
|
||||
*/
|
||||
static int arbel_command ( struct arbel *arbel, unsigned int op_fl,
|
||||
unsigned int op_mod, const void *in_param,
|
||||
size_t in_param_len, unsigned int in_mod,
|
||||
void *out_param, size_t out_param_len ) {
|
||||
static int arbel_cmd ( struct arbel *arbel, unsigned long command,
|
||||
unsigned int op_mod, const void *in,
|
||||
unsigned int in_mod, void *out ) {
|
||||
struct arbelprm_hca_command_register hcr;
|
||||
unsigned int opcode = ARBEL_HCR_OPCODE ( command );
|
||||
size_t in_len = ARBEL_HCR_IN_LEN ( command );
|
||||
size_t out_len = ARBEL_HCR_OUT_LEN ( command );
|
||||
void *in_buffer;
|
||||
void *out_buffer;
|
||||
unsigned int status;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
DBGC ( arbel, "Arbel %p command %02x in %zx%s out %zx%s\n",
|
||||
arbel, opcode, in_len,
|
||||
( ( command & ARBEL_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len,
|
||||
( ( command & ARBEL_HCR_OUT_MBOX ) ? "(mbox)" : "" ) );
|
||||
|
||||
/* Check that HCR is free */
|
||||
if ( ( rc = arbel_command_wait ( arbel, &hcr ) ) != 0 ) {
|
||||
if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
|
||||
DBGC ( arbel, "Arbel %p command interface locked\n", arbel );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Prepare HCR */
|
||||
memset ( &hcr, 0, sizeof ( hcr ) );
|
||||
if ( op_fl & ARBEL_HCR_IN_IMMEDIATE ) {
|
||||
memcpy ( &hcr.u.dwords[0], in_param, 8 );
|
||||
} else if ( op_fl & ARBEL_HCR_IN_MAILBOX ) {
|
||||
memcpy ( arbel->mailbox_in, in_param, in_param_len );
|
||||
MLX_FILL_1 ( &hcr, 1, in_param_l,
|
||||
virt_to_bus ( arbel->mailbox_in ) );
|
||||
in_buffer = &hcr.u.dwords[0];
|
||||
if ( in_len && ( command & ARBEL_HCR_IN_MBOX ) ) {
|
||||
in_buffer = arbel->mailbox_in;
|
||||
MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) );
|
||||
}
|
||||
memcpy ( in_buffer, in, in_len );
|
||||
MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod );
|
||||
if ( op_fl & ARBEL_HCR_OUT_MAILBOX ) {
|
||||
out_buffer = &hcr.u.dwords[3];
|
||||
if ( out_len && ( command & ARBEL_HCR_OUT_MBOX ) ) {
|
||||
out_buffer = arbel->mailbox_out;
|
||||
MLX_FILL_1 ( &hcr, 4, out_param_l,
|
||||
virt_to_bus ( arbel->mailbox_out ) );
|
||||
virt_to_bus ( out_buffer ) );
|
||||
}
|
||||
MLX_FILL_3 ( &hcr, 6,
|
||||
opcode, ( op_fl & ARBEL_HCR_OPCODE_MASK ),
|
||||
opcode, opcode,
|
||||
opcode_modifier, op_mod,
|
||||
go, 1 );
|
||||
|
||||
@ -343,7 +359,7 @@ static int arbel_command ( struct arbel *arbel, unsigned int op_fl,
|
||||
}
|
||||
|
||||
/* Wait for command completion */
|
||||
if ( ( rc = arbel_command_wait ( arbel, &hcr ) ) != 0 ) {
|
||||
if ( ( rc = arbel_cmd_wait ( arbel, &hcr ) ) != 0 ) {
|
||||
DBGC ( arbel, "Arbel %p timed out waiting for command:\n",
|
||||
arbel );
|
||||
DBGC_HD ( arbel, &hcr, sizeof ( hcr ) );
|
||||
@ -362,15 +378,19 @@ static int arbel_command ( struct arbel *arbel, unsigned int op_fl,
|
||||
/* Read output parameters, if any */
|
||||
hcr.u.dwords[3] = readl ( arbel->config + ARBEL_HCR_REG ( 3 ) );
|
||||
hcr.u.dwords[4] = readl ( arbel->config + ARBEL_HCR_REG ( 4 ) );
|
||||
if ( op_fl & ARBEL_HCR_OUT_IMMEDIATE ) {
|
||||
memcpy ( out_param, &hcr.u.dwords[3], 8 );
|
||||
} else if ( op_fl & ARBEL_HCR_OUT_MAILBOX ) {
|
||||
memcpy ( out_param, arbel->mailbox_out, out_param_len );
|
||||
}
|
||||
memcpy ( out, out_buffer, out_len );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arbel_cmd_query_dev_lim ( struct arbel *arbel,
|
||||
struct arbelprm_query_dev_lim *out ) {
|
||||
return arbel_cmd ( arbel,
|
||||
ARBEL_HCR_OUT_CMD ( ARBEL_HCR_QUERY_DEV_LIM,
|
||||
1, sizeof ( *out ) ),
|
||||
0, NULL, 0, out );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create completion queue
|
||||
*
|
||||
@ -752,15 +772,14 @@ static int arbel_probe ( struct pci_device *pci,
|
||||
list_add ( &static_ipoib_qp.recv.list,
|
||||
&static_ipoib_recv_cq.work_queues );
|
||||
|
||||
uint8_t buf[512];
|
||||
memset ( buf, 0xaa, sizeof ( buf ) );
|
||||
if ( ( rc = arbel_command ( &static_arbel,
|
||||
( 0x03 | ARBEL_HCR_OUT_MAILBOX ), 0,
|
||||
NULL, 0, 0, buf, 256 ) ) != 0 ) {
|
||||
struct arbelprm_query_dev_lim dev_lim;
|
||||
memset ( &dev_lim, 0xaa, sizeof ( dev_lim ) );
|
||||
if ( ( rc = arbel_cmd_query_dev_lim ( &static_arbel,
|
||||
&dev_lim ) ) != 0 ) {
|
||||
DBG ( "QUERY_DEV_LIM failed: %s\n", strerror ( rc ) );
|
||||
}
|
||||
DBG ( "Device limits:\n ");
|
||||
DBG_HD ( &buf[0], sizeof ( buf ) );
|
||||
DBG_HD ( &dev_lim, sizeof ( dev_lim ) );
|
||||
|
||||
/* Register network device */
|
||||
if ( ( rc = register_netdev ( netdev ) ) != 0 )
|
||||
|
Loading…
Reference in New Issue
Block a user