#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <errno.h>
#include <byteswap.h>
#include <gpxe/io.h>
#include <gpxe/pci.h>
#include <gpxe/pcibackup.h>
#include <gpxe/malloc.h>
#include <gpxe/umalloc.h>
#include <gpxe/iobuf.h>
#include <gpxe/netdevice.h>
#include <gpxe/infiniband.h>
#include <gpxe/ib_smc.h>
#include "hermon.h"
Go to the source code of this file.
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
| static int | hermon_bitmask_alloc (hermon_bitmask_t *bits, unsigned int bits_len, unsigned int num_bits) |
| Allocate offsets within usage bitmask. | |
| static void | hermon_bitmask_free (hermon_bitmask_t *bits, int bit, unsigned int num_bits) |
| Free offsets within usage bitmask. | |
| static int | hermon_cmd_wait (struct hermon *hermon, struct hermonprm_hca_command_register *hcr) |
| Wait for Hermon command completion. | |
| static int | hermon_cmd (struct hermon *hermon, unsigned long command, unsigned int op_mod, const void *in, unsigned int in_mod, void *out) |
| Issue HCA command. | |
| static int | hermon_cmd_query_dev_cap (struct hermon *hermon, struct hermonprm_query_dev_cap *dev_cap) |
| static int | hermon_cmd_query_fw (struct hermon *hermon, struct hermonprm_query_fw *fw) |
| static int | hermon_cmd_init_hca (struct hermon *hermon, const struct hermonprm_init_hca *init_hca) |
| static int | hermon_cmd_close_hca (struct hermon *hermon) |
| static int | hermon_cmd_init_port (struct hermon *hermon, unsigned int port, const struct hermonprm_init_port *init_port) |
| static int | hermon_cmd_close_port (struct hermon *hermon, unsigned int port) |
| static int | hermon_cmd_sw2hw_mpt (struct hermon *hermon, unsigned int index, const struct hermonprm_mpt *mpt) |
| static int | hermon_cmd_write_mtt (struct hermon *hermon, const struct hermonprm_write_mtt *write_mtt) |
| static int | hermon_cmd_map_eq (struct hermon *hermon, unsigned long index_map, const struct hermonprm_event_mask *mask) |
| static int | hermon_cmd_sw2hw_eq (struct hermon *hermon, unsigned int index, const struct hermonprm_eqc *eqctx) |
| static int | hermon_cmd_hw2sw_eq (struct hermon *hermon, unsigned int index, struct hermonprm_eqc *eqctx) |
| static int | hermon_cmd_query_eq (struct hermon *hermon, unsigned int index, struct hermonprm_eqc *eqctx) |
| static int | hermon_cmd_sw2hw_cq (struct hermon *hermon, unsigned long cqn, const struct hermonprm_completion_queue_context *cqctx) |
| static int | hermon_cmd_hw2sw_cq (struct hermon *hermon, unsigned long cqn, struct hermonprm_completion_queue_context *cqctx) |
| static int | hermon_cmd_rst2init_qp (struct hermon *hermon, unsigned long qpn, const struct hermonprm_qp_ee_state_transitions *ctx) |
| static int | hermon_cmd_init2rtr_qp (struct hermon *hermon, unsigned long qpn, const struct hermonprm_qp_ee_state_transitions *ctx) |
| static int | hermon_cmd_rtr2rts_qp (struct hermon *hermon, unsigned long qpn, const struct hermonprm_qp_ee_state_transitions *ctx) |
| static int | hermon_cmd_rts2rts_qp (struct hermon *hermon, unsigned long qpn, const struct hermonprm_qp_ee_state_transitions *ctx) |
| static int | hermon_cmd_2rst_qp (struct hermon *hermon, unsigned long qpn) |
| static int | hermon_cmd_query_qp (struct hermon *hermon, unsigned long qpn, struct hermonprm_qp_ee_state_transitions *ctx) |
| static int | hermon_cmd_conf_special_qp (struct hermon *hermon, unsigned int internal_qps, unsigned long base_qpn) |
| static int | hermon_cmd_mad_ifc (struct hermon *hermon, unsigned int port, union hermonprm_mad *mad) |
| static int | hermon_cmd_read_mcg (struct hermon *hermon, unsigned int index, struct hermonprm_mcg_entry *mcg) |
| static int | hermon_cmd_write_mcg (struct hermon *hermon, unsigned int index, const struct hermonprm_mcg_entry *mcg) |
| static int | hermon_cmd_mgid_hash (struct hermon *hermon, const struct ib_gid *gid, struct hermonprm_mgm_hash *hash) |
| static int | hermon_cmd_run_fw (struct hermon *hermon) |
| static int | hermon_cmd_unmap_icm (struct hermon *hermon, unsigned int page_count, const struct hermonprm_scalar_parameter *offset) |
| static int | hermon_cmd_map_icm (struct hermon *hermon, const struct hermonprm_virtual_physical_mapping *map) |
| static int | hermon_cmd_unmap_icm_aux (struct hermon *hermon) |
| static int | hermon_cmd_map_icm_aux (struct hermon *hermon, const struct hermonprm_virtual_physical_mapping *map) |
| static int | hermon_cmd_set_icm_size (struct hermon *hermon, const struct hermonprm_scalar_parameter *icm_size, struct hermonprm_scalar_parameter *icm_aux_size) |
| static int | hermon_cmd_unmap_fa (struct hermon *hermon) |
| static int | hermon_cmd_map_fa (struct hermon *hermon, const struct hermonprm_virtual_physical_mapping *map) |
| static int | hermon_cmd_sense_port (struct hermon *hermon, unsigned int port, struct hermonprm_sense_port *port_type) |
| static int | hermon_alloc_mtt (struct hermon *hermon, const void *memory, size_t len, struct hermon_mtt *mtt) |
| Allocate MTT entries. | |
| static void | hermon_free_mtt (struct hermon *hermon, struct hermon_mtt *mtt) |
| Free MTT entries. | |
| static int | hermon_mad (struct ib_device *ibdev, union ib_mad *mad) |
| Issue management datagram. | |
| static int | hermon_create_cq (struct ib_device *ibdev, struct ib_completion_queue *cq) |
| Create completion queue. | |
| static void | hermon_destroy_cq (struct ib_device *ibdev, struct ib_completion_queue *cq) |
| Destroy completion queue. | |
| static int | hermon_alloc_qpn (struct ib_device *ibdev, struct ib_queue_pair *qp) |
| Assign queue pair number. | |
| static void | hermon_free_qpn (struct ib_device *ibdev, struct ib_queue_pair *qp) |
| Free queue pair number. | |
| static unsigned int | hermon_rate (struct ib_address_vector *av) |
| Calculate transmission rate. | |
| static unsigned int | hermon_sched_queue (struct ib_device *ibdev, struct ib_queue_pair *qp) |
| Calculate schedule queue. | |
| static int | hermon_dump_qpctx (struct hermon *hermon, struct ib_queue_pair *qp) |
| Dump queue pair context (for debugging only). | |
| static int | hermon_create_qp (struct ib_device *ibdev, struct ib_queue_pair *qp) |
| Create queue pair. | |
| static int | hermon_modify_qp (struct ib_device *ibdev, struct ib_queue_pair *qp) |
| Modify queue pair. | |
| static void | hermon_destroy_qp (struct ib_device *ibdev, struct ib_queue_pair *qp) |
| Destroy queue pair. | |
| static unsigned int | hermon_fill_ud_send_wqe (struct ib_device *ibdev, struct ib_queue_pair *qp __unused, struct ib_address_vector *av, struct io_buffer *iobuf, union hermon_send_wqe *wqe) |
| Construct UD send work queue entry. | |
| static unsigned int | hermon_fill_mlx_send_wqe (struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, union hermon_send_wqe *wqe) |
| Construct MLX send work queue entry. | |
| static unsigned int | hermon_fill_rc_send_wqe (struct ib_device *ibdev, struct ib_queue_pair *qp __unused, struct ib_address_vector *av __unused, struct io_buffer *iobuf, union hermon_send_wqe *wqe) |
| Construct RC send work queue entry. | |
| static int | hermon_post_send (struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf) |
| Post send work queue entry. | |
| static int | hermon_post_recv (struct ib_device *ibdev, struct ib_queue_pair *qp, struct io_buffer *iobuf) |
| Post receive work queue entry. | |
| static int | hermon_complete (struct ib_device *ibdev, struct ib_completion_queue *cq, union hermonprm_completion_entry *cqe) |
| Handle completion. | |
| static void | hermon_poll_cq (struct ib_device *ibdev, struct ib_completion_queue *cq) |
| Poll completion queue. | |
| static int | hermon_create_eq (struct hermon *hermon) |
| Create event queue. | |
| static void | hermon_destroy_eq (struct hermon *hermon) |
| Destroy event queue. | |
| static void | hermon_event_port_state_change (struct hermon *hermon, union hermonprm_event_entry *eqe) |
| Handle port state event. | |
| static void | hermon_poll_eq (struct ib_device *ibdev) |
| Poll event queue. | |
| static int | hermon_sense_port_type (struct ib_device *ibdev) |
| Sense port type. | |
| static int | hermon_open (struct ib_device *ibdev) |
| Initialise Infiniband link. | |
| static void | hermon_close (struct ib_device *ibdev) |
| Close Infiniband link. | |
| static int | hermon_inform_sma (struct ib_device *ibdev, union ib_mad *mad) |
| Inform embedded subnet management agent of a received MAD. | |
| static int | hermon_mcast_attach (struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_gid *gid) |
| Attach to multicast group. | |
| static void | hermon_mcast_detach (struct ib_device *ibdev, struct ib_queue_pair *qp __unused, struct ib_gid *gid) |
| Detach from multicast group. | |
| static int | hermon_map_vpm (struct hermon *hermon, int(*map)(struct hermon *hermon, const struct hermonprm_virtual_physical_mapping *), uint64_t va, physaddr_t pa, size_t len) |
| Map virtual to physical address for firmware usage. | |
| static int | hermon_start_firmware (struct hermon *hermon) |
| Start firmware running. | |
| static void | hermon_stop_firmware (struct hermon *hermon) |
| Stop firmware running. | |
| static int | hermon_get_cap (struct hermon *hermon) |
| Get device limits. | |
| static size_t | icm_usage (unsigned int log_num_entries, size_t entry_size) |
| Get ICM usage. | |
| static size_t | icm_align (u32 member_size, u64 cur_icm_offset) |
| Align ICM. | |
| static int | hermon_alloc_icm (struct hermon *hermon, struct hermonprm_init_hca *init_hca) |
| Allocate ICM. | |
| static void | hermon_free_icm (struct hermon *hermon) |
| Free ICM. | |
| static int | hermon_setup_mpt (struct hermon *hermon) |
| Set up memory protection table. | |
| static int | hermon_configure_special_qps (struct hermon *hermon) |
| Configure special queue pairs. | |
| static void | hermon_reset (struct hermon *hermon, struct pci_device *pci) |
| Reset device. | |
| static int | hermon_probe (struct pci_device *pci, const struct pci_device_id *id __unused) |
| Probe PCI device. | |
| static void | hermon_remove (struct pci_device *pci) |
| Remove PCI device. | |
Variables | |
| static uint8_t | hermon_qp_st [] |
| Queue pair transport service type map. | |
| static unsigned int(* | hermon_fill_send_wqe [])(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, union hermon_send_wqe *wqe) |
| Work queue entry constructors. | |
| static struct ib_device_operations | hermon_ib_operations |
| Hermon Infiniband operations. | |
| static struct pci_device_id | hermon_nics [] |
| struct pci_driver hermon_driver | __pci_driver |
Definition in file hermon.c.
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
| static int hermon_bitmask_alloc | ( | hermon_bitmask_t * | bits, | |
| unsigned int | bits_len, | |||
| unsigned int | num_bits | |||
| ) | [static] |
Allocate offsets within usage bitmask.
| bits | Usage bitmask | |
| bits_len | Length of usage bitmask | |
| num_bits | Number of contiguous bits to allocate within bitmask |
| bit | First free bit within bitmask, or negative error |
Definition at line 63 of file hermon.c.
References ENFILE.
Referenced by hermon_alloc_mtt(), hermon_alloc_qpn(), and hermon_create_cq().
00065 { 00066 unsigned int bit = 0; 00067 hermon_bitmask_t mask = 1; 00068 unsigned int found = 0; 00069 00070 /* Search bits for num_bits contiguous free bits */ 00071 while ( bit < bits_len ) { 00072 if ( ( mask & *bits ) == 0 ) { 00073 if ( ++found == num_bits ) 00074 goto found; 00075 } else { 00076 found = 0; 00077 } 00078 bit++; 00079 mask = ( mask << 1 ) | ( mask >> ( 8 * sizeof ( mask ) - 1 ) ); 00080 if ( mask == 1 ) 00081 bits++; 00082 } 00083 return -ENFILE; 00084 00085 found: 00086 /* Mark bits as in-use */ 00087 do { 00088 *bits |= mask; 00089 if ( mask == 1 ) 00090 bits--; 00091 mask = ( mask >> 1 ) | ( mask << ( 8 * sizeof ( mask ) - 1 ) ); 00092 } while ( --found ); 00093 00094 return ( bit - num_bits + 1 ); 00095 }
| static void hermon_bitmask_free | ( | hermon_bitmask_t * | bits, | |
| int | bit, | |||
| unsigned int | num_bits | |||
| ) | [static] |
Free offsets within usage bitmask.
| bits | Usage bitmask | |
| bit | Starting bit within bitmask | |
| num_bits | Number of contiguous bits to free within bitmask |
Definition at line 104 of file hermon.c.
Referenced by hermon_alloc_mtt(), hermon_create_cq(), hermon_destroy_cq(), hermon_free_mtt(), and hermon_free_qpn().
00105 { 00106 hermon_bitmask_t mask; 00107 00108 for ( ; num_bits ; bit++, num_bits-- ) { 00109 mask = ( 1 << ( bit % ( 8 * sizeof ( mask ) ) ) ); 00110 bits[ ( bit / ( 8 * sizeof ( mask ) ) ) ] &= ~mask; 00111 } 00112 }
| static int hermon_cmd_wait | ( | struct hermon * | hermon, | |
| struct hermonprm_hca_command_register * | hcr | |||
| ) | [static] |
Wait for Hermon command completion.
| rc | Return status code |
Definition at line 128 of file hermon.c.
References hermon::config, EBUSY, HERMON_HCR_MAX_WAIT_MS, HERMON_HCR_REG, mdelay(), MLX_GET, readl, and hermon::toggle.
Referenced by hermon_cmd().
00129 { 00130 unsigned int wait; 00131 00132 for ( wait = HERMON_HCR_MAX_WAIT_MS ; wait ; wait-- ) { 00133 hcr->u.dwords[6] = 00134 readl ( hermon->config + HERMON_HCR_REG ( 6 ) ); 00135 if ( ( MLX_GET ( hcr, go ) == 0 ) && 00136 ( MLX_GET ( hcr, t ) == hermon->toggle ) ) 00137 return 0; 00138 mdelay ( 1 ); 00139 } 00140 return -EBUSY; 00141 }
| static int hermon_cmd | ( | struct hermon * | hermon, | |
| unsigned long | command, | |||
| unsigned int | op_mod, | |||
| const void * | in, | |||
| unsigned int | in_mod, | |||
| void * | out | |||
| ) | [static] |
Issue HCA command.
| hermon | Hermon device | |
| command | Command opcode, flags and input/output lengths | |
| op_mod | Opcode modifier (0 if no modifier applicable) | |
| in | Input parameters | |
| in_mod | Input modifier (0 if no modifier applicable) | |
| out | Output parameters |
| rc | Return status code |
Definition at line 154 of file hermon.c.
References assert, barrier, hermon::config, DBGC, DBGC2, DBGC2_HDA, DBGC_HDA, EIO, hermon_cmd_wait(), HERMON_HCR_BASE, HERMON_HCR_IN_LEN, HERMON_HCR_IN_MBOX, HERMON_HCR_OPCODE, HERMON_HCR_OUT_LEN, HERMON_HCR_OUT_MBOX, HERMON_HCR_REG, HERMON_MBOX_SIZE, hermon::mailbox_in, hermon::mailbox_out, memcpy, memset(), MLX_FILL_1, MLX_FILL_4, MLX_GET, readl, hermon::toggle, virt_to_bus(), virt_to_phys(), and writel.
Referenced by hermon_cmd_2rst_qp(), hermon_cmd_close_hca(), hermon_cmd_close_port(), hermon_cmd_conf_special_qp(), hermon_cmd_hw2sw_cq(), hermon_cmd_hw2sw_eq(), hermon_cmd_init2rtr_qp(), hermon_cmd_init_hca(), hermon_cmd_init_port(), hermon_cmd_mad_ifc(), hermon_cmd_map_eq(), hermon_cmd_map_fa(), hermon_cmd_map_icm(), hermon_cmd_map_icm_aux(), hermon_cmd_mgid_hash(), hermon_cmd_query_dev_cap(), hermon_cmd_query_eq(), hermon_cmd_query_fw(), hermon_cmd_query_qp(), hermon_cmd_read_mcg(), hermon_cmd_rst2init_qp(), hermon_cmd_rtr2rts_qp(), hermon_cmd_rts2rts_qp(), hermon_cmd_run_fw(), hermon_cmd_sense_port(), hermon_cmd_set_icm_size(), hermon_cmd_sw2hw_cq(), hermon_cmd_sw2hw_eq(), hermon_cmd_sw2hw_mpt(), hermon_cmd_unmap_fa(), hermon_cmd_unmap_icm(), hermon_cmd_unmap_icm_aux(), hermon_cmd_write_mcg(), and hermon_cmd_write_mtt().
00156 { 00157 struct hermonprm_hca_command_register hcr; 00158 unsigned int opcode = HERMON_HCR_OPCODE ( command ); 00159 size_t in_len = HERMON_HCR_IN_LEN ( command ); 00160 size_t out_len = HERMON_HCR_OUT_LEN ( command ); 00161 void *in_buffer; 00162 void *out_buffer; 00163 unsigned int status; 00164 unsigned int i; 00165 int rc; 00166 00167 assert ( in_len <= HERMON_MBOX_SIZE ); 00168 assert ( out_len <= HERMON_MBOX_SIZE ); 00169 00170 DBGC2 ( hermon, "Hermon %p command %02x in %zx%s out %zx%s\n", 00171 hermon, opcode, in_len, 00172 ( ( command & HERMON_HCR_IN_MBOX ) ? "(mbox)" : "" ), out_len, 00173 ( ( command & HERMON_HCR_OUT_MBOX ) ? "(mbox)" : "" ) ); 00174 00175 /* Check that HCR is free */ 00176 if ( ( rc = hermon_cmd_wait ( hermon, &hcr ) ) != 0 ) { 00177 DBGC ( hermon, "Hermon %p command interface locked\n", 00178 hermon ); 00179 return rc; 00180 } 00181 00182 /* Flip HCR toggle */ 00183 hermon->toggle = ( 1 - hermon->toggle ); 00184 00185 /* Prepare HCR */ 00186 memset ( &hcr, 0, sizeof ( hcr ) ); 00187 in_buffer = &hcr.u.dwords[0]; 00188 if ( in_len && ( command & HERMON_HCR_IN_MBOX ) ) { 00189 in_buffer = hermon->mailbox_in; 00190 MLX_FILL_1 ( &hcr, 1, in_param_l, virt_to_bus ( in_buffer ) ); 00191 } 00192 memcpy ( in_buffer, in, in_len ); 00193 MLX_FILL_1 ( &hcr, 2, input_modifier, in_mod ); 00194 out_buffer = &hcr.u.dwords[3]; 00195 if ( out_len && ( command & HERMON_HCR_OUT_MBOX ) ) { 00196 out_buffer = hermon->mailbox_out; 00197 MLX_FILL_1 ( &hcr, 4, out_param_l, 00198 virt_to_bus ( out_buffer ) ); 00199 } 00200 MLX_FILL_4 ( &hcr, 6, 00201 opcode, opcode, 00202 opcode_modifier, op_mod, 00203 go, 1, 00204 t, hermon->toggle ); 00205 DBGC ( hermon, "Hermon %p issuing command %04x\n", 00206 hermon, opcode ); 00207 DBGC2_HDA ( hermon, virt_to_phys ( hermon->config + HERMON_HCR_BASE ), 00208 &hcr, sizeof ( hcr ) ); 00209 if ( in_len && ( command & HERMON_HCR_IN_MBOX ) ) { 00210 DBGC2 ( hermon, "Input mailbox:\n" ); 00211 DBGC2_HDA ( hermon, virt_to_phys ( in_buffer ), in_buffer, 00212 ( ( in_len < 512 ) ? in_len : 512 ) ); 00213 } 00214 00215 /* Issue command */ 00216 for ( i = 0 ; i < ( sizeof ( hcr ) / sizeof ( hcr.u.dwords[0] ) ) ; 00217 i++ ) { 00218 writel ( hcr.u.dwords[i], 00219 hermon->config + HERMON_HCR_REG ( i ) ); 00220 barrier(); 00221 } 00222 00223 /* Wait for command completion */ 00224 if ( ( rc = hermon_cmd_wait ( hermon, &hcr ) ) != 0 ) { 00225 DBGC ( hermon, "Hermon %p timed out waiting for command:\n", 00226 hermon ); 00227 DBGC_HDA ( hermon, 00228 virt_to_phys ( hermon->config + HERMON_HCR_BASE ), 00229 &hcr, sizeof ( hcr ) ); 00230 return rc; 00231 } 00232 00233 /* Check command status */ 00234 status = MLX_GET ( &hcr, status ); 00235 if ( status != 0 ) { 00236 DBGC ( hermon, "Hermon %p command failed with status %02x:\n", 00237 hermon, status ); 00238 DBGC_HDA ( hermon, 00239 virt_to_phys ( hermon->config + HERMON_HCR_BASE ), 00240 &hcr, sizeof ( hcr ) ); 00241 return -EIO; 00242 } 00243 00244 /* Read output parameters, if any */ 00245 hcr.u.dwords[3] = readl ( hermon->config + HERMON_HCR_REG ( 3 ) ); 00246 hcr.u.dwords[4] = readl ( hermon->config + HERMON_HCR_REG ( 4 ) ); 00247 memcpy ( out, out_buffer, out_len ); 00248 if ( out_len ) { 00249 DBGC2 ( hermon, "Output%s:\n", 00250 ( command & HERMON_HCR_OUT_MBOX ) ? " mailbox" : "" ); 00251 DBGC2_HDA ( hermon, virt_to_phys ( out_buffer ), out_buffer, 00252 ( ( out_len < 512 ) ? out_len : 512 ) ); 00253 } 00254 00255 return 0; 00256 }
| static int hermon_cmd_query_dev_cap | ( | struct hermon * | hermon, | |
| struct hermonprm_query_dev_cap * | dev_cap | |||
| ) | [inline, static] |
Definition at line 259 of file hermon.c.
References hermon_cmd(), HERMON_HCR_OUT_CMD, HERMON_HCR_QUERY_DEV_CAP, and NULL.
Referenced by hermon_get_cap().
00260 { 00261 return hermon_cmd ( hermon, 00262 HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_DEV_CAP, 00263 1, sizeof ( *dev_cap ) ), 00264 0, NULL, 0, dev_cap ); 00265 }
| static int hermon_cmd_query_fw | ( | struct hermon * | hermon, | |
| struct hermonprm_query_fw * | fw | |||
| ) | [inline, static] |
Definition at line 268 of file hermon.c.
References hermon_cmd(), HERMON_HCR_OUT_CMD, HERMON_HCR_QUERY_FW, and NULL.
Referenced by hermon_start_firmware().
00268 { 00269 return hermon_cmd ( hermon, 00270 HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_FW, 00271 1, sizeof ( *fw ) ), 00272 0, NULL, 0, fw ); 00273 }
| static int hermon_cmd_init_hca | ( | struct hermon * | hermon, | |
| const struct hermonprm_init_hca * | init_hca | |||
| ) | [inline, static] |
Definition at line 276 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_INIT_HCA, and NULL.
Referenced by hermon_probe().
00277 { 00278 return hermon_cmd ( hermon, 00279 HERMON_HCR_IN_CMD ( HERMON_HCR_INIT_HCA, 00280 1, sizeof ( *init_hca ) ), 00281 0, init_hca, 0, NULL ); 00282 }
| static int hermon_cmd_close_hca | ( | struct hermon * | hermon | ) | [inline, static] |
Definition at line 285 of file hermon.c.
References hermon_cmd(), HERMON_HCR_CLOSE_HCA, HERMON_HCR_VOID_CMD, and NULL.
Referenced by hermon_probe(), and hermon_remove().
00285 { 00286 return hermon_cmd ( hermon, 00287 HERMON_HCR_VOID_CMD ( HERMON_HCR_CLOSE_HCA ), 00288 0, NULL, 0, NULL ); 00289 }
| static int hermon_cmd_init_port | ( | struct hermon * | hermon, | |
| unsigned int | port, | |||
| const struct hermonprm_init_port * | init_port | |||
| ) | [inline, static] |
Definition at line 292 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_INIT_PORT, and NULL.
Referenced by hermon_open().
00293 { 00294 return hermon_cmd ( hermon, 00295 HERMON_HCR_IN_CMD ( HERMON_HCR_INIT_PORT, 00296 1, sizeof ( *init_port ) ), 00297 0, init_port, port, NULL ); 00298 }
| static int hermon_cmd_close_port | ( | struct hermon * | hermon, | |
| unsigned int | port | |||
| ) | [inline, static] |
Definition at line 301 of file hermon.c.
References hermon_cmd(), HERMON_HCR_CLOSE_PORT, HERMON_HCR_VOID_CMD, and NULL.
Referenced by hermon_close().
00301 { 00302 return hermon_cmd ( hermon, 00303 HERMON_HCR_VOID_CMD ( HERMON_HCR_CLOSE_PORT ), 00304 0, NULL, port, NULL ); 00305 }
| static int hermon_cmd_sw2hw_mpt | ( | struct hermon * | hermon, | |
| unsigned int | index, | |||
| const struct hermonprm_mpt * | mpt | |||
| ) | [inline, static] |
Definition at line 308 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_SW2HW_MPT, and NULL.
Referenced by hermon_setup_mpt().
00309 { 00310 return hermon_cmd ( hermon, 00311 HERMON_HCR_IN_CMD ( HERMON_HCR_SW2HW_MPT, 00312 1, sizeof ( *mpt ) ), 00313 0, mpt, index, NULL ); 00314 }
| static int hermon_cmd_write_mtt | ( | struct hermon * | hermon, | |
| const struct hermonprm_write_mtt * | write_mtt | |||
| ) | [inline, static] |
Definition at line 317 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_WRITE_MTT, and NULL.
Referenced by hermon_alloc_mtt().
00318 { 00319 return hermon_cmd ( hermon, 00320 HERMON_HCR_IN_CMD ( HERMON_HCR_WRITE_MTT, 00321 1, sizeof ( *write_mtt ) ), 00322 0, write_mtt, 1, NULL ); 00323 }
| static int hermon_cmd_map_eq | ( | struct hermon * | hermon, | |
| unsigned long | index_map, | |||
| const struct hermonprm_event_mask * | mask | |||
| ) | [inline, static] |
Definition at line 326 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_MAP_EQ, and NULL.
Referenced by hermon_create_eq(), and hermon_destroy_eq().
00327 { 00328 return hermon_cmd ( hermon, 00329 HERMON_HCR_IN_CMD ( HERMON_HCR_MAP_EQ, 00330 0, sizeof ( *mask ) ), 00331 0, mask, index_map, NULL ); 00332 }
| static int hermon_cmd_sw2hw_eq | ( | struct hermon * | hermon, | |
| unsigned int | index, | |||
| const struct hermonprm_eqc * | eqctx | |||
| ) | [inline, static] |
Definition at line 335 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_SW2HW_EQ, and NULL.
Referenced by hermon_create_eq().
00336 { 00337 return hermon_cmd ( hermon, 00338 HERMON_HCR_IN_CMD ( HERMON_HCR_SW2HW_EQ, 00339 1, sizeof ( *eqctx ) ), 00340 0, eqctx, index, NULL ); 00341 }
| static int hermon_cmd_hw2sw_eq | ( | struct hermon * | hermon, | |
| unsigned int | index, | |||
| struct hermonprm_eqc * | eqctx | |||
| ) | [inline, static] |
Definition at line 344 of file hermon.c.
References hermon_cmd(), HERMON_HCR_HW2SW_EQ, HERMON_HCR_OUT_CMD, and NULL.
Referenced by hermon_create_eq(), and hermon_destroy_eq().
00345 { 00346 return hermon_cmd ( hermon, 00347 HERMON_HCR_OUT_CMD ( HERMON_HCR_HW2SW_EQ, 00348 1, sizeof ( *eqctx ) ), 00349 1, NULL, index, eqctx ); 00350 }
| static int hermon_cmd_query_eq | ( | struct hermon * | hermon, | |
| unsigned int | index, | |||
| struct hermonprm_eqc * | eqctx | |||
| ) | [inline, static] |
Definition at line 353 of file hermon.c.
References hermon_cmd(), HERMON_HCR_OUT_CMD, HERMON_HCR_QUERY_EQ, and NULL.
00354 { 00355 return hermon_cmd ( hermon, 00356 HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_EQ, 00357 1, sizeof ( *eqctx ) ), 00358 0, NULL, index, eqctx ); 00359 }
| static int hermon_cmd_sw2hw_cq | ( | struct hermon * | hermon, | |
| unsigned long | cqn, | |||
| const struct hermonprm_completion_queue_context * | cqctx | |||
| ) | [inline, static] |
Definition at line 362 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_SW2HW_CQ, and NULL.
Referenced by hermon_create_cq().
00363 { 00364 return hermon_cmd ( hermon, 00365 HERMON_HCR_IN_CMD ( HERMON_HCR_SW2HW_CQ, 00366 1, sizeof ( *cqctx ) ), 00367 0, cqctx, cqn, NULL ); 00368 }
| static int hermon_cmd_hw2sw_cq | ( | struct hermon * | hermon, | |
| unsigned long | cqn, | |||
| struct hermonprm_completion_queue_context * | cqctx | |||
| ) | [inline, static] |
Definition at line 371 of file hermon.c.
References hermon_cmd(), HERMON_HCR_HW2SW_CQ, HERMON_HCR_OUT_CMD, and NULL.
Referenced by hermon_destroy_cq().
00372 { 00373 return hermon_cmd ( hermon, 00374 HERMON_HCR_OUT_CMD ( HERMON_HCR_HW2SW_CQ, 00375 1, sizeof ( *cqctx ) ), 00376 0, NULL, cqn, cqctx ); 00377 }
| static int hermon_cmd_rst2init_qp | ( | struct hermon * | hermon, | |
| unsigned long | qpn, | |||
| const struct hermonprm_qp_ee_state_transitions * | ctx | |||
| ) | [inline, static] |
Definition at line 380 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_RST2INIT_QP, and NULL.
Referenced by hermon_create_qp().
00381 { 00382 return hermon_cmd ( hermon, 00383 HERMON_HCR_IN_CMD ( HERMON_HCR_RST2INIT_QP, 00384 1, sizeof ( *ctx ) ), 00385 0, ctx, qpn, NULL ); 00386 }
| static int hermon_cmd_init2rtr_qp | ( | struct hermon * | hermon, | |
| unsigned long | qpn, | |||
| const struct hermonprm_qp_ee_state_transitions * | ctx | |||
| ) | [inline, static] |
Definition at line 389 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_INIT2RTR_QP, and NULL.
Referenced by hermon_modify_qp().
00390 { 00391 return hermon_cmd ( hermon, 00392 HERMON_HCR_IN_CMD ( HERMON_HCR_INIT2RTR_QP, 00393 1, sizeof ( *ctx ) ), 00394 0, ctx, qpn, NULL ); 00395 }
| static int hermon_cmd_rtr2rts_qp | ( | struct hermon * | hermon, | |
| unsigned long | qpn, | |||
| const struct hermonprm_qp_ee_state_transitions * | ctx | |||
| ) | [inline, static] |
Definition at line 398 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_RTR2RTS_QP, and NULL.
Referenced by hermon_modify_qp().
00399 { 00400 return hermon_cmd ( hermon, 00401 HERMON_HCR_IN_CMD ( HERMON_HCR_RTR2RTS_QP, 00402 1, sizeof ( *ctx ) ), 00403 0, ctx, qpn, NULL ); 00404 }
| static int hermon_cmd_rts2rts_qp | ( | struct hermon * | hermon, | |
| unsigned long | qpn, | |||
| const struct hermonprm_qp_ee_state_transitions * | ctx | |||
| ) | [inline, static] |
Definition at line 407 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_RTS2RTS_QP, and NULL.
Referenced by hermon_modify_qp().
00408 { 00409 return hermon_cmd ( hermon, 00410 HERMON_HCR_IN_CMD ( HERMON_HCR_RTS2RTS_QP, 00411 1, sizeof ( *ctx ) ), 00412 0, ctx, qpn, NULL ); 00413 }
| static int hermon_cmd_2rst_qp | ( | struct hermon * | hermon, | |
| unsigned long | qpn | |||
| ) | [inline, static] |
Definition at line 416 of file hermon.c.
References hermon_cmd(), HERMON_HCR_2RST_QP, HERMON_HCR_VOID_CMD, and NULL.
Referenced by hermon_create_qp(), and hermon_destroy_qp().
00416 { 00417 return hermon_cmd ( hermon, 00418 HERMON_HCR_VOID_CMD ( HERMON_HCR_2RST_QP ), 00419 0x03, NULL, qpn, NULL ); 00420 }
| static int hermon_cmd_query_qp | ( | struct hermon * | hermon, | |
| unsigned long | qpn, | |||
| struct hermonprm_qp_ee_state_transitions * | ctx | |||
| ) | [inline, static] |
Definition at line 423 of file hermon.c.
References hermon_cmd(), HERMON_HCR_OUT_CMD, HERMON_HCR_QUERY_QP, and NULL.
Referenced by hermon_dump_qpctx().
00424 { 00425 return hermon_cmd ( hermon, 00426 HERMON_HCR_OUT_CMD ( HERMON_HCR_QUERY_QP, 00427 1, sizeof ( *ctx ) ), 00428 0, NULL, qpn, ctx ); 00429 }
| static int hermon_cmd_conf_special_qp | ( | struct hermon * | hermon, | |
| unsigned int | internal_qps, | |||
| unsigned long | base_qpn | |||
| ) | [inline, static] |
Definition at line 432 of file hermon.c.
References hermon_cmd(), HERMON_HCR_CONF_SPECIAL_QP, HERMON_HCR_VOID_CMD, and NULL.
Referenced by hermon_configure_special_qps().
00433 { 00434 return hermon_cmd ( hermon, 00435 HERMON_HCR_VOID_CMD ( HERMON_HCR_CONF_SPECIAL_QP ), 00436 internal_qps, NULL, base_qpn, NULL ); 00437 }
| static int hermon_cmd_mad_ifc | ( | struct hermon * | hermon, | |
| unsigned int | port, | |||
| union hermonprm_mad * | mad | |||
| ) | [inline, static] |
Definition at line 440 of file hermon.c.
References hermon_cmd(), HERMON_HCR_INOUT_CMD, and HERMON_HCR_MAD_IFC.
Referenced by hermon_mad().
00441 { 00442 return hermon_cmd ( hermon, 00443 HERMON_HCR_INOUT_CMD ( HERMON_HCR_MAD_IFC, 00444 1, sizeof ( *mad ), 00445 1, sizeof ( *mad ) ), 00446 0x03, mad, port, mad ); 00447 }
| static int hermon_cmd_read_mcg | ( | struct hermon * | hermon, | |
| unsigned int | index, | |||
| struct hermonprm_mcg_entry * | mcg | |||
| ) | [inline, static] |
Definition at line 450 of file hermon.c.
References hermon_cmd(), HERMON_HCR_OUT_CMD, HERMON_HCR_READ_MCG, and NULL.
Referenced by hermon_mcast_attach().
00451 { 00452 return hermon_cmd ( hermon, 00453 HERMON_HCR_OUT_CMD ( HERMON_HCR_READ_MCG, 00454 1, sizeof ( *mcg ) ), 00455 0, NULL, index, mcg ); 00456 }
| static int hermon_cmd_write_mcg | ( | struct hermon * | hermon, | |
| unsigned int | index, | |||
| const struct hermonprm_mcg_entry * | mcg | |||
| ) | [inline, static] |
Definition at line 459 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_WRITE_MCG, and NULL.
Referenced by hermon_mcast_attach(), and hermon_mcast_detach().
00460 { 00461 return hermon_cmd ( hermon, 00462 HERMON_HCR_IN_CMD ( HERMON_HCR_WRITE_MCG, 00463 1, sizeof ( *mcg ) ), 00464 0, mcg, index, NULL ); 00465 }
| static int hermon_cmd_mgid_hash | ( | struct hermon * | hermon, | |
| const struct ib_gid * | gid, | |||
| struct hermonprm_mgm_hash * | hash | |||
| ) | [inline, static] |
Definition at line 468 of file hermon.c.
References hermon_cmd(), HERMON_HCR_INOUT_CMD, and HERMON_HCR_MGID_HASH.
Referenced by hermon_mcast_attach(), and hermon_mcast_detach().
00469 { 00470 return hermon_cmd ( hermon, 00471 HERMON_HCR_INOUT_CMD ( HERMON_HCR_MGID_HASH, 00472 1, sizeof ( *gid ), 00473 0, sizeof ( *hash ) ), 00474 0, gid, 0, hash ); 00475 }
| static int hermon_cmd_run_fw | ( | struct hermon * | hermon | ) | [inline, static] |
Definition at line 478 of file hermon.c.
References hermon_cmd(), HERMON_HCR_RUN_FW, HERMON_HCR_VOID_CMD, and NULL.
Referenced by hermon_start_firmware().
00478 { 00479 return hermon_cmd ( hermon, 00480 HERMON_HCR_VOID_CMD ( HERMON_HCR_RUN_FW ), 00481 0, NULL, 0, NULL ); 00482 }
| static int hermon_cmd_unmap_icm | ( | struct hermon * | hermon, | |
| unsigned int | page_count, | |||
| const struct hermonprm_scalar_parameter * | offset | |||
| ) | [inline, static] |
Definition at line 485 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_UNMAP_ICM, and NULL.
Referenced by hermon_free_icm().
00486 { 00487 return hermon_cmd ( hermon, 00488 HERMON_HCR_IN_CMD ( HERMON_HCR_UNMAP_ICM, 00489 0, sizeof ( *offset ) ), 00490 0, offset, page_count, NULL ); 00491 }
| static int hermon_cmd_map_icm | ( | struct hermon * | hermon, | |
| const struct hermonprm_virtual_physical_mapping * | map | |||
| ) | [inline, static] |
Definition at line 494 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_MAP_ICM, and NULL.
Referenced by hermon_alloc_icm().
00495 { 00496 return hermon_cmd ( hermon, 00497 HERMON_HCR_IN_CMD ( HERMON_HCR_MAP_ICM, 00498 1, sizeof ( *map ) ), 00499 0, map, 1, NULL ); 00500 }
| static int hermon_cmd_unmap_icm_aux | ( | struct hermon * | hermon | ) | [inline, static] |
Definition at line 503 of file hermon.c.
References hermon_cmd(), HERMON_HCR_UNMAP_ICM_AUX, HERMON_HCR_VOID_CMD, and NULL.
Referenced by hermon_alloc_icm(), and hermon_free_icm().
00503 { 00504 return hermon_cmd ( hermon, 00505 HERMON_HCR_VOID_CMD ( HERMON_HCR_UNMAP_ICM_AUX ), 00506 0, NULL, 0, NULL ); 00507 }
| static int hermon_cmd_map_icm_aux | ( | struct hermon * | hermon, | |
| const struct hermonprm_virtual_physical_mapping * | map | |||
| ) | [inline, static] |
Definition at line 510 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_MAP_ICM_AUX, and NULL.
Referenced by hermon_alloc_icm().
00511 { 00512 return hermon_cmd ( hermon, 00513 HERMON_HCR_IN_CMD ( HERMON_HCR_MAP_ICM_AUX, 00514 1, sizeof ( *map ) ), 00515 0, map, 1, NULL ); 00516 }
| static int hermon_cmd_set_icm_size | ( | struct hermon * | hermon, | |
| const struct hermonprm_scalar_parameter * | icm_size, | |||
| struct hermonprm_scalar_parameter * | icm_aux_size | |||
| ) | [inline, static] |
Definition at line 519 of file hermon.c.
References hermon_cmd(), HERMON_HCR_INOUT_CMD, and HERMON_HCR_SET_ICM_SIZE.
Referenced by hermon_alloc_icm().
00521 { 00522 return hermon_cmd ( hermon, 00523 HERMON_HCR_INOUT_CMD ( HERMON_HCR_SET_ICM_SIZE, 00524 0, sizeof ( *icm_size ), 00525 0, sizeof (*icm_aux_size) ), 00526 0, icm_size, 0, icm_aux_size ); 00527 }
| static int hermon_cmd_unmap_fa | ( | struct hermon * | hermon | ) | [inline, static] |
Definition at line 530 of file hermon.c.
References hermon_cmd(), HERMON_HCR_UNMAP_FA, HERMON_HCR_VOID_CMD, and NULL.
Referenced by hermon_start_firmware(), and hermon_stop_firmware().
00530 { 00531 return hermon_cmd ( hermon, 00532 HERMON_HCR_VOID_CMD ( HERMON_HCR_UNMAP_FA ), 00533 0, NULL, 0, NULL ); 00534 }
| static int hermon_cmd_map_fa | ( | struct hermon * | hermon, | |
| const struct hermonprm_virtual_physical_mapping * | map | |||
| ) | [inline, static] |
Definition at line 537 of file hermon.c.
References hermon_cmd(), HERMON_HCR_IN_CMD, HERMON_HCR_MAP_FA, and NULL.
Referenced by hermon_start_firmware().
00538 { 00539 return hermon_cmd ( hermon, 00540 HERMON_HCR_IN_CMD ( HERMON_HCR_MAP_FA, 00541 1, sizeof ( *map ) ), 00542 0, map, 1, NULL ); 00543 }
| static int hermon_cmd_sense_port | ( | struct hermon * | hermon, | |
| unsigned int | port, | |||
| struct hermonprm_sense_port * | port_type | |||
| ) | [inline, static] |
Definition at line 546 of file hermon.c.
References hermon_cmd(), HERMON_HCR_OUT_CMD, HERMON_HCR_SENSE_PORT, and NULL.
Referenced by hermon_sense_port_type().
00547 { 00548 return hermon_cmd ( hermon, 00549 HERMON_HCR_OUT_CMD ( HERMON_HCR_SENSE_PORT, 00550 1, sizeof ( *port_type ) ), 00551 0, NULL, port, port_type ); 00552 }
| static int hermon_alloc_mtt | ( | struct hermon * | hermon, | |
| const void * | memory, | |||
| size_t | len, | |||
| struct hermon_mtt * | mtt | |||
| ) | [static] |
Allocate MTT entries.
| hermon | Hermon device | |
| memory | Memory to map into MTT | |
| len | Length of memory to map | |
| mtt | MTT descriptor to fill in |
| rc | Return status code |
Definition at line 571 of file hermon.c.
References hermon::cap, DBGC, hermon_bitmask_alloc(), hermon_bitmask_free(), hermon_cmd_write_mtt(), HERMON_MAX_MTTS, HERMON_PAGE_SIZE, memset(), MLX_FILL_1, MLX_FILL_2, hermonprm_write_mtt::mtt, hermon_mtt::mtt_base_addr, hermonprm_write_mtt::mtt_base_addr, hermon_dev_cap::mtt_entry_size, hermon::mtt_inuse, hermon_mtt::mtt_offset, hermon_mtt::num_pages, hermon_mtt::page_offset, hermon_dev_cap::reserved_mtts, and virt_to_phys().
Referenced by hermon_create_cq(), hermon_create_eq(), and hermon_create_qp().
00573 { 00574 struct hermonprm_write_mtt write_mtt; 00575 physaddr_t start; 00576 unsigned int page_offset; 00577 unsigned int num_pages; 00578 int mtt_offset; 00579 unsigned int mtt_base_addr; 00580 unsigned int i; 00581 int rc; 00582 00583 /* Find available MTT entries */ 00584 start = virt_to_phys ( memory ); 00585 page_offset = ( start & ( HERMON_PAGE_SIZE - 1 ) ); 00586 start -= page_offset; 00587 len += page_offset; 00588 num_pages = ( ( len + HERMON_PAGE_SIZE - 1 ) / HERMON_PAGE_SIZE ); 00589 mtt_offset = hermon_bitmask_alloc ( hermon->mtt_inuse, HERMON_MAX_MTTS, 00590 num_pages ); 00591 if ( mtt_offset < 0 ) { 00592 DBGC ( hermon, "Hermon %p could not allocate %d MTT entries\n", 00593 hermon, num_pages ); 00594 rc = mtt_offset; 00595 goto err_mtt_offset; 00596 } 00597 mtt_base_addr = ( ( hermon->cap.reserved_mtts + mtt_offset ) * 00598 hermon->cap.mtt_entry_size ); 00599 00600 /* Fill in MTT structure */ 00601 mtt->mtt_offset = mtt_offset; 00602 mtt->num_pages = num_pages; 00603 mtt->mtt_base_addr = mtt_base_addr; 00604 mtt->page_offset = page_offset; 00605 00606 /* Construct and issue WRITE_MTT commands */ 00607 for ( i = 0 ; i < num_pages ; i++ ) { 00608 memset ( &write_mtt, 0, sizeof ( write_mtt ) ); 00609 MLX_FILL_1 ( &write_mtt.mtt_base_addr, 1, 00610 value, mtt_base_addr ); 00611 MLX_FILL_2 ( &write_mtt.mtt, 1, 00612 p, 1, 00613 ptag_l, ( start >> 3 ) ); 00614 if ( ( rc = hermon_cmd_write_mtt ( hermon, 00615 &write_mtt ) ) != 0 ) { 00616 DBGC ( hermon, "Hermon %p could not write MTT at %x\n", 00617 hermon, mtt_base_addr ); 00618 goto err_write_mtt; 00619 } 00620 start += HERMON_PAGE_SIZE; 00621 mtt_base_addr += hermon->cap.mtt_entry_size; 00622 } 00623 00624 return 0; 00625 00626 err_write_mtt: 00627 hermon_bitmask_free ( hermon->mtt_inuse, mtt_offset, num_pages ); 00628 err_mtt_offset: 00629 return rc; 00630 }
| static void hermon_free_mtt | ( | struct hermon * | hermon, | |
| struct hermon_mtt * | mtt | |||
| ) | [static] |
Free MTT entries.
Definition at line 638 of file hermon.c.
References hermon_bitmask_free(), hermon::mtt_inuse, hermon_mtt::mtt_offset, and hermon_mtt::num_pages.
Referenced by hermon_create_cq(), hermon_create_eq(), hermon_create_qp(), hermon_destroy_cq(), hermon_destroy_eq(), and hermon_destroy_qp().
00639 { 00640 hermon_bitmask_free ( hermon->mtt_inuse, mtt->mtt_offset, 00641 mtt->num_pages ); 00642 }
Issue management datagram.
| ibdev | Infiniband device | |
| mad | Management datagram |
| rc | Return status code |
Definition at line 658 of file hermon.c.
References DBGC, EIO, ib_mad::hdr, hermon_cmd_mad_ifc(), ib_get_drvdata(), linker_assert, hermonprm_mad::mad, memcpy, ntohs, ib_device::port, ib_mad_hdr::status, and strerror().
Referenced by hermon_event_port_state_change(), hermon_inform_sma(), hermon_open(), and hermon_probe().
00658 { 00659 struct hermon *hermon = ib_get_drvdata ( ibdev ); 00660 union hermonprm_mad mad_ifc; 00661 int rc; 00662 00663 linker_assert ( sizeof ( *mad ) == sizeof ( mad_ifc.mad ), 00664 mad_size_mismatch ); 00665 00666 /* Copy in request packet */ 00667 memcpy ( &mad_ifc.mad, mad, sizeof ( mad_ifc.mad ) ); 00668 00669 /* Issue MAD */ 00670 if ( ( rc = hermon_cmd_mad_ifc ( hermon, ibdev->port, 00671 &mad_ifc ) ) != 0 ) { 00672 DBGC ( hermon, "Hermon %p could not issue MAD IFC: %s\n", 00673 hermon, strerror ( rc ) ); 00674 return rc; 00675 } 00676 00677 /* Copy out reply packet */ 00678 memcpy ( mad, &mad_ifc.mad, sizeof ( *mad ) ); 00679 00680 if ( mad->hdr.status != 0 ) { 00681 DBGC ( hermon, "Hermon %p MAD IFC status %04x\n", 00682 hermon, ntohs ( mad->hdr.status ) ); 00683 return -EIO; 00684 } 00685 return 0; 00686 }
| static int hermon_create_cq | ( | struct ib_device * | ibdev, | |
| struct ib_completion_queue * | cq | |||
| ) | [static] |
Create completion queue.
| ibdev | Infiniband device | |
| cq | Completion queue |
| rc | Return status code |
Definition at line 702 of file hermon.c.
References barrier, hermon::cap, hermon::cq_inuse, hermon_completion_queue::cqe, hermon_completion_queue::cqe_size, ib_completion_queue::cqn, DBGC, ENOMEM, fls, free(), free_dma(), hermon_alloc_mtt(), hermon_bitmask_alloc(), hermon_bitmask_free(), hermon_cmd_sw2hw_cq(), hermon_free_mtt(), HERMON_MAX_CQS, HERMON_UAR_NON_EQ_PAGE, ib_cq_set_drvdata(), ib_get_drvdata(), malloc_dma(), memset(), MLX_FILL_1, MLX_FILL_2, hermon_completion_queue::mtt, hermon_mtt::mtt_base_addr, hermonprm_completion_entry::normal, ib_completion_queue::num_cqes, hermon_mtt::page_offset, hermon_dev_cap::reserved_cqs, strerror(), virt_to_phys(), and zalloc().
00703 { 00704 struct hermon *hermon = ib_get_drvdata ( ibdev ); 00705 struct hermon_completion_queue *hermon_cq; 00706 struct hermonprm_completion_queue_context cqctx; 00707 int cqn_offset; 00708 unsigned int i; 00709 int rc; 00710 00711 /* Find a free completion queue number */ 00712 cqn_offset = hermon_bitmask_alloc ( hermon->cq_inuse, 00713 HERMON_MAX_CQS, 1 ); 00714 if ( cqn_offset < 0 ) { 00715 DBGC ( hermon, "Hermon %p out of completion queues\n", 00716 hermon ); 00717 rc = cqn_offset; 00718 goto err_cqn_offset; 00719 } 00720 cq->cqn = ( hermon->cap.reserved_cqs + cqn_offset ); 00721 00722 /* Allocate control structures */ 00723 hermon_cq = zalloc ( sizeof ( *hermon_cq ) ); 00724 if ( ! hermon_cq ) { 00725 rc = -ENOMEM; 00726 goto err_hermon_cq; 00727 } 00728 00729 /* Allocate completion queue itself */ 00730 hermon_cq->cqe_size = ( cq->num_cqes * sizeof ( hermon_cq->cqe[0] ) ); 00731 hermon_cq->cqe = malloc_dma ( hermon_cq->cqe_size, 00732 sizeof ( hermon_cq->cqe[0] ) ); 00733 if ( ! hermon_cq->cqe ) { 00734 rc = -ENOMEM; 00735 goto err_cqe; 00736 } 00737 memset ( hermon_cq->cqe, 0, hermon_cq->cqe_size ); 00738 for ( i = 0 ; i < cq->num_cqes ; i++ ) { 00739 MLX_FILL_1 ( &hermon_cq->cqe[i].normal, 7, owner, 1 ); 00740 } 00741 barrier(); 00742 00743 /* Allocate MTT entries */ 00744 if ( ( rc = hermon_alloc_mtt ( hermon, hermon_cq->cqe, 00745 hermon_cq->cqe_size, 00746 &hermon_cq->mtt ) ) != 0 ) 00747 goto err_alloc_mtt; 00748 00749 /* Hand queue over to hardware */ 00750 memset ( &cqctx, 0, sizeof ( cqctx ) ); 00751 MLX_FILL_1 ( &cqctx, 0, st, 0xa /* "Event fired" */ ); 00752 MLX_FILL_1 ( &cqctx, 2, 00753 page_offset, ( hermon_cq->mtt.page_offset >> 5 ) ); 00754 MLX_FILL_2 ( &cqctx, 3, 00755 usr_page, HERMON_UAR_NON_EQ_PAGE, 00756 log_cq_size, fls ( cq->num_cqes - 1 ) ); 00757 MLX_FILL_1 ( &cqctx, 7, mtt_base_addr_l, 00758 ( hermon_cq->mtt.mtt_base_addr >> 3 ) ); 00759 MLX_FILL_1 ( &cqctx, 15, db_record_addr_l, 00760 ( virt_to_phys ( &hermon_cq->doorbell ) >> 3 ) ); 00761 if ( ( rc = hermon_cmd_sw2hw_cq ( hermon, cq->cqn, &cqctx ) ) != 0 ) { 00762 DBGC ( hermon, "Hermon %p SW2HW_CQ failed: %s\n", 00763 hermon, strerror ( rc ) ); 00764 goto err_sw2hw_cq; 00765 } 00766 00767 DBGC ( hermon, "Hermon %p CQN %#lx ring at [%p,%p)\n", 00768 hermon, cq->cqn, hermon_cq->cqe, 00769 ( ( ( void * ) hermon_cq->cqe ) + hermon_cq->cqe_size ) ); 00770 ib_cq_set_drvdata ( cq, hermon_cq ); 00771 return 0; 00772 00773 err_sw2hw_cq: 00774 hermon_free_mtt ( hermon, &hermon_cq->mtt ); 00775 err_alloc_mtt: 00776 free_dma ( hermon_cq->cqe, hermon_cq->cqe_size ); 00777 err_cqe: 00778 free ( hermon_cq ); 00779 err_hermon_cq: 00780 hermon_bitmask_free ( hermon->cq_inuse, cqn_offset, 1 ); 00781 err_cqn_offset: 00782 return rc; 00783 }
| static void hermon_destroy_cq | ( | struct ib_device * | ibdev, | |
| struct ib_completion_queue * | cq | |||
| ) | [static] |
Destroy completion queue.
| ibdev | Infiniband device | |
| cq | Completion queue |
Definition at line 791 of file hermon.c.
References hermon::cap, hermon::cq_inuse, hermon_completion_queue::cqe, hermon_completion_queue::cqe_size, ib_completion_queue::cqn, DBGC, free(), free_dma(), hermon_bitmask_free(), hermon_cmd_hw2sw_cq(), hermon_free_mtt(), ib_cq_get_drvdata(), ib_cq_set_drvdata(), ib_get_drvdata(), hermon_completion_queue::mtt, NULL, hermon_dev_cap::reserved_cqs, and strerror().
00792 { 00793 struct hermon *hermon = ib_get_drvdata ( ibdev ); 00794 struct hermon_completion_queue *hermon_cq = ib_cq_get_drvdata ( cq ); 00795 struct hermonprm_completion_queue_context cqctx; 00796 int cqn_offset; 00797 int rc; 00798 00799 /* Take ownership back from hardware */ 00800 if ( ( rc = hermon_cmd_hw2sw_cq ( hermon, cq->cqn, &cqctx ) ) != 0 ) { 00801 DBGC ( hermon, "Hermon %p FATAL HW2SW_CQ failed on CQN %#lx: " 00802 "%s\n", hermon, cq->cqn, strerror ( rc ) ); 00803 /* Leak memory and return; at least we avoid corruption */ 00804 return; 00805 } 00806 00807 /* Free MTT entries */ 00808 hermon_free_mtt ( hermon, &hermon_cq->mtt ); 00809 00810 /* Free memory */ 00811 free_dma ( hermon_cq->cqe, hermon_cq->cqe_size ); 00812 free ( hermon_cq ); 00813 00814 /* Mark queue number as free */ 00815 cqn_offset = ( cq->cqn - hermon->cap.reserved_cqs ); 00816 hermon_bitmask_free ( hermon->cq_inuse, cqn_offset, 1 ); 00817 00818 ib_cq_set_drvdata ( cq, NULL ); 00819 }
| static int hermon_alloc_qpn | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp | |||
| ) | [static] |
Assign queue pair number.
| ibdev | Infiniband device | |
| qp | Queue pair |
| rc | Return status code |
Definition at line 835 of file hermon.c.
References DBGC, ENOTSUP, hermon_bitmask_alloc(), HERMON_MAX_QPS, HERMON_PORT_BASE, HERMON_QPN_RANDOM_MASK, ib_get_drvdata(), IB_QPT_GSI, IB_QPT_RC, IB_QPT_SMI, IB_QPT_UD, ib_device::port, hermon::qp_inuse, ib_queue_pair::qpn, hermon::qpn_base, random(), hermon::special_qpn_base, and ib_queue_pair::type.
Referenced by hermon_create_qp().
00836 { 00837 struct hermon *hermon = ib_get_drvdata ( ibdev ); 00838 unsigned int port_offset; 00839 int qpn_offset; 00840 00841 /* Calculate queue pair number */ 00842 port_offset = ( ibdev->port - HERMON_PORT_BASE ); 00843 00844 switch ( qp->type ) { 00845 case IB_QPT_SMI: 00846 qp->qpn = ( hermon->special_qpn_base + port_offset ); 00847 return 0; 00848 case IB_QPT_GSI: 00849 qp->qpn = ( hermon->special_qpn_base + 2 + port_offset ); 00850 return 0; 00851 case IB_QPT_UD: 00852 case IB_QPT_RC: 00853 /* Find a free queue pair number */ 00854 qpn_offset = hermon_bitmask_alloc ( hermon->qp_inuse, 00855 HERMON_MAX_QPS, 1 ); 00856 if ( qpn_offset < 0 ) { 00857 DBGC ( hermon, "Hermon %p out of queue pairs\n", 00858 hermon ); 00859 return qpn_offset; 00860 } 00861 qp->qpn = ( ( random() & HERMON_QPN_RANDOM_MASK ) | 00862 ( hermon->qpn_base + qpn_offset ) ); 00863 return 0; 00864 default: 00865 DBGC ( hermon, "Hermon %p unsupported QP type %d\n", 00866 hermon, qp->type ); 00867 return -ENOTSUP; 00868 } 00869 }
| static void hermon_free_qpn | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp | |||
| ) | [static] |
Free queue pair number.
| ibdev | Infiniband device | |
| qp | Queue pair |
Definition at line 877 of file hermon.c.
References hermon_bitmask_free(), HERMON_QPN_RANDOM_MASK, ib_get_drvdata(), hermon::qp_inuse, ib_queue_pair::qpn, and hermon::qpn_base.
Referenced by hermon_create_qp(), and hermon_destroy_qp().
00878 { 00879 struct hermon *hermon = ib_get_drvdata ( ibdev ); 00880 int qpn_offset; 00881 00882 qpn_offset = ( ( qp->qpn & ~HERMON_QPN_RANDOM_MASK ) 00883 - hermon->qpn_base ); 00884 if ( qpn_offset >= 0 ) 00885 hermon_bitmask_free ( hermon->qp_inuse, qpn_offset, 1 ); 00886 }
| static unsigned int hermon_rate | ( | struct ib_address_vector * | av | ) | [static] |
Calculate transmission rate.
| av | Address vector |
| hermon_rate | Hermon rate |
Definition at line 894 of file hermon.c.
References IB_RATE_120, IB_RATE_2_5, and ib_address_vector::rate.
Referenced by hermon_fill_mlx_send_wqe(), hermon_fill_ud_send_wqe(), and hermon_modify_qp().
00894 { 00895 return ( ( ( av->rate >= IB_RATE_2_5 ) && ( av->rate <= IB_RATE_120 ) ) 00896 ? ( av->rate + 5 ) : 0 ); 00897 }
| static unsigned int hermon_sched_queue | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp | |||
| ) | [static] |
Calculate schedule queue.
| ibdev | Infiniband device | |
| qp | Queue pair |
| sched_queue | Schedule queue |
Definition at line 906 of file hermon.c.
References HERMON_SCHED_DEFAULT, HERMON_SCHED_QP0, IB_QPT_SMI, ib_device::port, and ib_queue_pair::type.
Referenced by hermon_modify_qp().
00907 { 00908 return ( ( ( qp->type == IB_QPT_SMI ) ? 00909 HERMON_SCHED_QP0 : HERMON_SCHED_DEFAULT ) | 00910 ( ( ibdev->port - 1 ) << 6 ) ); 00911 }
| static int hermon_dump_qpctx | ( | struct hermon * | hermon, | |
| struct ib_queue_pair * | qp | |||
| ) | [inline, static] |
Dump queue pair context (for debugging only).
| rc | Return status code |
Definition at line 928 of file hermon.c.
References DBGC, DBGC_HDA, hermon_cmd_query_qp(), memset(), ib_queue_pair::qpn, and strerror().
00929 { 00930 struct hermonprm_qp_ee_state_transitions qpctx; 00931 int rc; 00932 00933 memset ( &qpctx, 0, sizeof ( qpctx ) ); 00934 if ( ( rc = hermon_cmd_query_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ) { 00935 DBGC ( hermon, "Hermon %p QUERY_QP failed: %s\n", 00936 hermon, strerror ( rc ) ); 00937 return rc; 00938 } 00939 DBGC ( hermon, "Hermon %p QPN %lx context:\n", hermon, qp->qpn ); 00940 DBGC_HDA ( hermon, 0, &qpctx.u.dwords[2], 00941 ( sizeof ( qpctx ) - 8 ) ); 00942 00943 return 0; 00944 }
| static int hermon_create_qp | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp | |||
| ) | [static] |
Create queue pair.
| ibdev | Infiniband device | |
| qp | Queue pair |
| rc | Return status code |
Definition at line 953 of file hermon.c.
References ib_work_queue::cq, ib_completion_queue::cqn, DBGC, hermon_send_work_queue::doorbell, ENOMEM, fls, free(), free_dma(), hermon_alloc_mtt(), hermon_alloc_qpn(), hermon_cmd_2rst_qp(), hermon_cmd_rst2init_qp(), HERMON_DB_POST_SND_OFFSET, hermon_free_mtt(), hermon_free_qpn(), HERMON_GLOBAL_PD, HERMON_PAGE_SIZE, HERMON_PM_STATE_MIGRATED, hermon_qp_st, HERMON_QP_ST_INIT, HERMON_UAR_NON_EQ_PAGE, ib_get_drvdata(), ib_qp_set_drvdata(), malloc_dma(), memset(), MLX_FILL_1, MLX_FILL_2, MLX_FILL_4, hermon_queue_pair::mtt, hermon_mtt::mtt_base_addr, ib_work_queue::num_wqes, hermon_send_work_queue::num_wqes, hermon_mtt::page_offset, ib_queue_pair::qpn, ib_queue_pair::recv, hermon_queue_pair::recv, ib_queue_pair::send, hermon_queue_pair::send, hermon_queue_pair::state, strerror(), ib_queue_pair::type, hermon::uar, virt_to_phys(), hermon_queue_pair::wqe, hermon_recv_work_queue::wqe, hermon_send_work_queue::wqe, hermon_queue_pair::wqe_size, hermon_recv_work_queue::wqe_size, hermon_send_work_queue::wqe_size, and zalloc().
00954 { 00955 struct hermon *hermon = ib_get_drvdata ( ibdev ); 00956 struct hermon_queue_pair *hermon_qp; 00957 struct hermonprm_qp_ee_state_transitions qpctx; 00958 int rc; 00959 00960 /* Calculate queue pair number */ 00961 if ( ( rc = hermon_alloc_qpn ( ibdev, qp ) ) != 0 ) 00962 goto err_alloc_qpn; 00963 00964 /* Allocate control structures */ 00965 hermon_qp = zalloc ( sizeof ( *hermon_qp ) ); 00966 if ( ! hermon_qp ) { 00967 rc = -ENOMEM; 00968 goto err_hermon_qp; 00969 } 00970 00971 /* Calculate doorbell address */ 00972 hermon_qp->send.doorbell = 00973 ( hermon->uar + HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE + 00974 HERMON_DB_POST_SND_OFFSET ); 00975 00976 /* Allocate work queue buffer */ 00977 hermon_qp->send.num_wqes = ( qp->send.num_wqes /* headroom */ + 1 + 00978 ( 2048 / sizeof ( hermon_qp->send.wqe[0] ) ) ); 00979 hermon_qp->send.num_wqes = 00980 ( 1 << fls ( hermon_qp->send.num_wqes - 1 ) ); /* round up */ 00981 hermon_qp->send.wqe_size = ( hermon_qp->send.num_wqes * 00982 sizeof ( hermon_qp->send.wqe[0] ) ); 00983 hermon_qp->recv.wqe_size = ( qp->recv.num_wqes * 00984 sizeof ( hermon_qp->recv.wqe[0] ) ); 00985 hermon_qp->wqe_size = ( hermon_qp->send.wqe_size + 00986 hermon_qp->recv.wqe_size ); 00987 hermon_qp->wqe = malloc_dma ( hermon_qp->wqe_size, 00988 sizeof ( hermon_qp->send.wqe[0] ) ); 00989 if ( ! hermon_qp->wqe ) { 00990 rc = -ENOMEM; 00991 goto err_alloc_wqe; 00992 } 00993 hermon_qp->send.wqe = hermon_qp->wqe; 00994 memset ( hermon_qp->send.wqe, 0xff, hermon_qp->send.wqe_size ); 00995 hermon_qp->recv.wqe = ( hermon_qp->wqe + hermon_qp->send.wqe_size ); 00996 memset ( hermon_qp->recv.wqe, 0, hermon_qp->recv.wqe_size ); 00997 00998 /* Allocate MTT entries */ 00999 if ( ( rc = hermon_alloc_mtt ( hermon, hermon_qp->wqe, 01000 hermon_qp->wqe_size, 01001 &hermon_qp->mtt ) ) != 0 ) { 01002 goto err_alloc_mtt; 01003 } 01004 01005 /* Transition queue to INIT state */ 01006 memset ( &qpctx, 0, sizeof ( qpctx ) ); 01007 MLX_FILL_2 ( &qpctx, 2, 01008 qpc_eec_data.pm_state, HERMON_PM_STATE_MIGRATED, 01009 qpc_eec_data.st, hermon_qp_st[qp->type] ); 01010 MLX_FILL_1 ( &qpctx, 3, qpc_eec_data.pd, HERMON_GLOBAL_PD ); 01011 MLX_FILL_4 ( &qpctx, 4, 01012 qpc_eec_data.log_rq_size, fls ( qp->recv.num_wqes - 1 ), 01013 qpc_eec_data.log_rq_stride, 01014 ( fls ( sizeof ( hermon_qp->recv.wqe[0] ) - 1 ) - 4 ), 01015 qpc_eec_data.log_sq_size, 01016 fls ( hermon_qp->send.num_wqes - 1 ), 01017 qpc_eec_data.log_sq_stride, 01018 ( fls ( sizeof ( hermon_qp->send.wqe[0] ) - 1 ) - 4 ) ); 01019 MLX_FILL_1 ( &qpctx, 5, 01020 qpc_eec_data.usr_page, HERMON_UAR_NON_EQ_PAGE ); 01021 MLX_FILL_1 ( &qpctx, 33, qpc_eec_data.cqn_snd, qp->send.cq->cqn ); 01022 MLX_FILL_4 ( &qpctx, 38, 01023 qpc_eec_data.rre, 1, 01024 qpc_eec_data.rwe, 1, 01025 qpc_eec_data.rae, 1, 01026 qpc_eec_data.page_offset, 01027 ( hermon_qp->mtt.page_offset >> 6 ) ); 01028 MLX_FILL_1 ( &qpctx, 41, qpc_eec_data.cqn_rcv, qp->recv.cq->cqn ); 01029 MLX_FILL_1 ( &qpctx, 43, qpc_eec_data.db_record_addr_l, 01030 ( virt_to_phys ( &hermon_qp->recv.doorbell ) >> 2 ) ); 01031 MLX_FILL_1 ( &qpctx, 53, qpc_eec_data.mtt_base_addr_l, 01032 ( hermon_qp->mtt.mtt_base_addr >> 3 ) ); 01033 if ( ( rc = hermon_cmd_rst2init_qp ( hermon, qp->qpn, 01034 &qpctx ) ) != 0 ) { 01035 DBGC ( hermon, "Hermon %p RST2INIT_QP failed: %s\n", 01036 hermon, strerror ( rc ) ); 01037 goto err_rst2init_qp; 01038 } 01039 hermon_qp->state = HERMON_QP_ST_INIT; 01040 01041 DBGC ( hermon, "Hermon %p QPN %#lx send ring at [%p,%p)\n", 01042 hermon, qp->qpn, hermon_qp->send.wqe, 01043 ( ((void *)hermon_qp->send.wqe ) + hermon_qp->send.wqe_size ) ); 01044 DBGC ( hermon, "Hermon %p QPN %#lx receive ring at [%p,%p)\n", 01045 hermon, qp->qpn, hermon_qp->recv.wqe, 01046 ( ((void *)hermon_qp->recv.wqe ) + hermon_qp->recv.wqe_size ) ); 01047 ib_qp_set_drvdata ( qp, hermon_qp ); 01048 return 0; 01049 01050 hermon_cmd_2rst_qp ( hermon, qp->qpn ); 01051 err_rst2init_qp: 01052 hermon_free_mtt ( hermon, &hermon_qp->mtt ); 01053 err_alloc_mtt: 01054 free_dma ( hermon_qp->wqe, hermon_qp->wqe_size ); 01055 err_alloc_wqe: 01056 free ( hermon_qp ); 01057 err_hermon_qp: 01058 hermon_free_qpn ( ibdev, qp ); 01059 err_alloc_qpn: 01060 return rc; 01061 }
| static int hermon_modify_qp | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp | |||
| ) | [static] |
Modify queue pair.
| ibdev | Infiniband device | |
| qp | Queue pair |
| rc | Return status code |
Definition at line 1070 of file hermon.c.
References ib_queue_pair::av, DBGC, ib_address_vector::gid, hermon_cmd_init2rtr_qp(), hermon_cmd_rtr2rts_qp(), hermon_cmd_rts2rts_qp(), HERMON_MTU_2048, HERMON_QP_OPT_PARAM_QKEY, HERMON_QP_ST_RTR, HERMON_QP_ST_RTS, hermon_rate(), HERMON_RETRY_MAX, hermon_sched_queue(), ib_get_drvdata(), ib_qp_get_drvdata(), ib_address_vector::lid, memcpy, memset(), MLX_FILL_1, MLX_FILL_2, ib_work_queue::psn, ib_queue_pair::qkey, ib_queue_pair::qpn, ib_address_vector::qpn, ib_queue_pair::recv, ib_queue_pair::send, hermon_queue_pair::state, and strerror().
01071 { 01072 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01073 struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp ); 01074 struct hermonprm_qp_ee_state_transitions qpctx; 01075 int rc; 01076 01077 /* Transition queue to RTR state, if applicable */ 01078 if ( hermon_qp->state < HERMON_QP_ST_RTR ) { 01079 memset ( &qpctx, 0, sizeof ( qpctx ) ); 01080 MLX_FILL_2 ( &qpctx, 4, 01081 qpc_eec_data.mtu, HERMON_MTU_2048, 01082 qpc_eec_data.msg_max, 31 ); 01083 MLX_FILL_1 ( &qpctx, 7, 01084 qpc_eec_data.remote_qpn_een, qp->av.qpn ); 01085 MLX_FILL_1 ( &qpctx, 9, 01086 qpc_eec_data.primary_address_path.rlid, 01087 qp->av.lid ); 01088 MLX_FILL_1 ( &qpctx, 10, 01089 qpc_eec_data.primary_address_path.max_stat_rate, 01090 hermon_rate ( &qp->av ) ); 01091 memcpy ( &qpctx.u.dwords[12], &qp->av.gid, 01092 sizeof ( qp->av.gid ) ); 01093 MLX_FILL_1 ( &qpctx, 16, 01094 qpc_eec_data.primary_address_path.sched_queue, 01095 hermon_sched_queue ( ibdev, qp ) ); 01096 MLX_FILL_1 ( &qpctx, 39, 01097 qpc_eec_data.next_rcv_psn, qp->recv.psn ); 01098 if ( ( rc = hermon_cmd_init2rtr_qp ( hermon, qp->qpn, 01099 &qpctx ) ) != 0 ) { 01100 DBGC ( hermon, "Hermon %p INIT2RTR_QP failed: %s\n", 01101 hermon, strerror ( rc ) ); 01102 return rc; 01103 } 01104 hermon_qp->state = HERMON_QP_ST_RTR; 01105 } 01106 01107 /* Transition queue to RTS state */ 01108 if ( hermon_qp->state < HERMON_QP_ST_RTS ) { 01109 memset ( &qpctx, 0, sizeof ( qpctx ) ); 01110 MLX_FILL_1 ( &qpctx, 10, 01111 qpc_eec_data.primary_address_path.ack_timeout, 01112 14 /* 4.096us * 2^(14) = 67ms */ ); 01113 MLX_FILL_2 ( &qpctx, 30, 01114 qpc_eec_data.retry_count, HERMON_RETRY_MAX, 01115 qpc_eec_data.rnr_retry, HERMON_RETRY_MAX ); 01116 MLX_FILL_1 ( &qpctx, 32, 01117 qpc_eec_data.next_send_psn, qp->send.psn ); 01118 if ( ( rc = hermon_cmd_rtr2rts_qp ( hermon, qp->qpn, 01119 &qpctx ) ) != 0 ) { 01120 DBGC ( hermon, "Hermon %p RTR2RTS_QP failed: %s\n", 01121 hermon, strerror ( rc ) ); 01122 return rc; 01123 } 01124 hermon_qp->state = HERMON_QP_ST_RTS; 01125 } 01126 01127 /* Update parameters in RTS state */ 01128 memset ( &qpctx, 0, sizeof ( qpctx ) ); 01129 MLX_FILL_1 ( &qpctx, 0, opt_param_mask, HERMON_QP_OPT_PARAM_QKEY ); 01130 MLX_FILL_1 ( &qpctx, 44, qpc_eec_data.q_key, qp->qkey ); 01131 if ( ( rc = hermon_cmd_rts2rts_qp ( hermon, qp->qpn, &qpctx ) ) != 0 ){ 01132 DBGC ( hermon, "Hermon %p RTS2RTS_QP failed: %s\n", 01133 hermon, strerror ( rc ) ); 01134 return rc; 01135 } 01136 01137 return 0; 01138 }
| static void hermon_destroy_qp | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp | |||
| ) | [static] |
Destroy queue pair.
| ibdev | Infiniband device | |
| qp | Queue pair |
Definition at line 1146 of file hermon.c.
References DBGC, free(), free_dma(), hermon_cmd_2rst_qp(), hermon_free_mtt(), hermon_free_qpn(), ib_get_drvdata(), ib_qp_get_drvdata(), ib_qp_set_drvdata(), hermon_queue_pair::mtt, NULL, ib_queue_pair::qpn, strerror(), hermon_queue_pair::wqe, and hermon_queue_pair::wqe_size.
01147 { 01148 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01149 struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp ); 01150 int rc; 01151 01152 /* Take ownership back from hardware */ 01153 if ( ( rc = hermon_cmd_2rst_qp ( hermon, qp->qpn ) ) != 0 ) { 01154 DBGC ( hermon, "Hermon %p FATAL 2RST_QP failed on QPN %#lx: " 01155 "%s\n", hermon, qp->qpn, strerror ( rc ) ); 01156 /* Leak memory and return; at least we avoid corruption */ 01157 return; 01158 } 01159 01160 /* Free MTT entries */ 01161 hermon_free_mtt ( hermon, &hermon_qp->mtt ); 01162 01163 /* Free memory */ 01164 free_dma ( hermon_qp->wqe, hermon_qp->wqe_size ); 01165 free ( hermon_qp ); 01166 01167 /* Mark queue number as free */ 01168 hermon_free_qpn ( ibdev, qp ); 01169 01170 ib_qp_set_drvdata ( qp, NULL ); 01171 }
| static unsigned int hermon_fill_ud_send_wqe | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair *qp | __unused, | |||
| struct ib_address_vector * | av, | |||
| struct io_buffer * | iobuf, | |||
| union hermon_send_wqe * | wqe | |||
| ) | [static] |
Construct UD send work queue entry.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| av | Address vector | |
| iobuf | I/O buffer | |
| wqe | Send work queue entry |
| opcode | Control opcode |
Definition at line 1191 of file hermon.c.
References hermonprm_ud_send_wqe::ctrl, io_buffer::data, hermonprm_ud_send_wqe::data, ib_address_vector::gid, ib_address_vector::gid_present, HERMON_GLOBAL_PD, HERMON_OPCODE_SEND, hermon_rate(), ib_get_drvdata(), iob_len(), ib_address_vector::lid, hermon::lkey, memcpy, MLX_FILL_1, MLX_FILL_2, offsetof, ib_device::port, ib_address_vector::qkey, ib_address_vector::qpn, ib_address_vector::sl, hermonprm_ud_send_wqe::ud, hermon_send_wqe::ud, and virt_to_bus().
01195 { 01196 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01197 01198 MLX_FILL_1 ( &wqe->ud.ctrl, 1, ds, 01199 ( ( offsetof ( typeof ( wqe->ud ), data[1] ) / 16 ) ) ); 01200 MLX_FILL_1 ( &wqe->ud.ctrl, 2, c, 0x03 /* generate completion */ ); 01201 MLX_FILL_2 ( &wqe->ud.ud, 0, 01202 ud_address_vector.pd, HERMON_GLOBAL_PD, 01203 ud_address_vector.port_number, ibdev->port ); 01204 MLX_FILL_2 ( &wqe->ud.ud, 1, 01205 ud_address_vector.rlid, av->lid, 01206 ud_address_vector.g, av->gid_present ); 01207 MLX_FILL_1 ( &wqe->ud.ud, 2, 01208 ud_address_vector.max_stat_rate, hermon_rate ( av ) ); 01209 MLX_FILL_1 ( &wqe->ud.ud, 3, ud_address_vector.sl, av->sl ); 01210 memcpy ( &wqe->ud.ud.u.dwords[4], &av->gid, sizeof ( av->gid ) ); 01211 MLX_FILL_1 ( &wqe->ud.ud, 8, destination_qp, av->qpn ); 01212 MLX_FILL_1 ( &wqe->ud.ud, 9, q_key, av->qkey ); 01213 MLX_FILL_1 ( &wqe->ud.data[0], 0, byte_count, iob_len ( iobuf ) ); 01214 MLX_FILL_1 ( &wqe->ud.data[0], 1, l_key, hermon->lkey ); 01215 MLX_FILL_1 ( &wqe->ud.data[0], 3, 01216 local_address_l, virt_to_bus ( iobuf->data ) ); 01217 return HERMON_OPCODE_SEND; 01218 }
| static unsigned int hermon_fill_mlx_send_wqe | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp, | |||
| struct ib_address_vector * | av, | |||
| struct io_buffer * | iobuf, | |||
| union hermon_send_wqe * | wqe | |||
| ) | [static] |
Construct MLX send work queue entry.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| av | Address vector | |
| iobuf | I/O buffer | |
| wqe | Send work queue entry |
| opcode | Control opcode |
Definition at line 1231 of file hermon.c.
References hermonprm_mlx_send_wqe::ctrl, hermonprm_mlx_send_wqe::data, io_buffer::data, ib_queue_pair::ext_qpn, hermonprm_mlx_send_wqe::headers, HERMON_OPCODE_SEND, hermon_rate(), ib_get_drvdata(), ib_push(), IB_QPN_SMI, iob_len(), iob_populate(), iob_reserve, ib_address_vector::lid, hermon::lkey, hermon_send_wqe::mlx, MLX_FILL_1, MLX_FILL_5, offsetof, and virt_to_bus().
01235 { 01236 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01237 struct io_buffer headers; 01238 01239 /* Construct IB headers */ 01240 iob_populate ( &headers, &wqe->mlx.headers, 0, 01241 sizeof ( wqe->mlx.headers ) ); 01242 iob_reserve ( &headers, sizeof ( wqe->mlx.headers ) ); 01243 ib_push ( ibdev, &headers, qp, iob_len ( iobuf ), av ); 01244 01245 /* Fill work queue entry */ 01246 MLX_FILL_1 ( &wqe->mlx.ctrl, 1, ds, 01247 ( ( offsetof ( typeof ( wqe->mlx ), data[2] ) / 16 ) ) ); 01248 MLX_FILL_5 ( &wqe->mlx.ctrl, 2, 01249 c, 0x03 /* generate completion */, 01250 icrc, 0 /* generate ICRC */, 01251 max_statrate, hermon_rate ( av ), 01252 slr, 0, 01253 v15, ( ( qp->ext_qpn == IB_QPN_SMI ) ? 1 : 0 ) ); 01254 MLX_FILL_1 ( &wqe->mlx.ctrl, 3, rlid, av->lid ); 01255 MLX_FILL_1 ( &wqe->mlx.data[0], 0, 01256 byte_count, iob_len ( &headers ) ); 01257 MLX_FILL_1 ( &wqe->mlx.data[0], 1, l_key, hermon->lkey ); 01258 MLX_FILL_1 ( &wqe->mlx.data[0], 3, 01259 local_address_l, virt_to_bus ( headers.data ) ); 01260 MLX_FILL_1 ( &wqe->mlx.data[1], 0, 01261 byte_count, ( iob_len ( iobuf ) + 4 /* ICRC */ ) ); 01262 MLX_FILL_1 ( &wqe->mlx.data[1], 1, l_key, hermon->lkey ); 01263 MLX_FILL_1 ( &wqe->mlx.data[1], 3, 01264 local_address_l, virt_to_bus ( iobuf->data ) ); 01265 return HERMON_OPCODE_SEND; 01266 }
| static unsigned int hermon_fill_rc_send_wqe | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair *qp | __unused, | |||
| struct ib_address_vector *av | __unused, | |||
| struct io_buffer * | iobuf, | |||
| union hermon_send_wqe * | wqe | |||
| ) | [static] |
Construct RC send work queue entry.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| av | Address vector | |
| iobuf | I/O buffer | |
| wqe | Send work queue entry |
| opcode | Control opcode |
Definition at line 1279 of file hermon.c.
References hermonprm_rc_send_wqe::ctrl, io_buffer::data, hermonprm_rc_send_wqe::data, HERMON_OPCODE_SEND, ib_get_drvdata(), iob_len(), hermon::lkey, MLX_FILL_1, offsetof, hermon_send_wqe::rc, and virt_to_bus().
01283 { 01284 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01285 01286 MLX_FILL_1 ( &wqe->rc.ctrl, 1, ds, 01287 ( ( offsetof ( typeof ( wqe->rc ), data[1] ) / 16 ) ) ); 01288 MLX_FILL_1 ( &wqe->rc.ctrl, 2, c, 0x03 /* generate completion */ ); 01289 MLX_FILL_1 ( &wqe->rc.data[0], 0, byte_count, iob_len ( iobuf ) ); 01290 MLX_FILL_1 ( &wqe->rc.data[0], 1, l_key, hermon->lkey ); 01291 MLX_FILL_1 ( &wqe->rc.data[0], 3, 01292 local_address_l, virt_to_bus ( iobuf->data ) ); 01293 return HERMON_OPCODE_SEND; 01294 }
| static int hermon_post_send | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp, | |||
| struct ib_address_vector * | av, | |||
| struct io_buffer * | iobuf | |||
| ) | [static] |
Post send work queue entry.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| av | Address vector | |
| iobuf | I/O buffer |
| rc | Return status code |
Definition at line 1318 of file hermon.c.
References assert, barrier, DBGC, DBGCP, DBGCP_HD, hermon_send_work_queue::doorbell, hermonprm_doorbell_register::dword, ENOBUFS, hermon_fill_send_wqe, ib_get_drvdata(), ib_qp_get_drvdata(), ib_work_queue::iobufs, memset(), MLX_FILL_1, MLX_FILL_2, ib_work_queue::next_idx, NULL, hermon_send_work_queue::num_wqes, ib_work_queue::num_wqes, hermonprm_doorbell_register::send, hermon_queue_pair::send, ib_queue_pair::send, ib_queue_pair::type, virt_to_phys(), hermon_send_work_queue::wqe, and writel.
01321 { 01322 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01323 struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp ); 01324 struct ib_work_queue *wq = &qp->send; 01325 struct hermon_send_work_queue *hermon_send_wq = &hermon_qp->send; 01326 union hermon_send_wqe *wqe; 01327 union hermonprm_doorbell_register db_reg; 01328 unsigned int wqe_idx_mask; 01329 unsigned int opcode; 01330 01331 /* Allocate work queue entry */ 01332 wqe_idx_mask = ( wq->num_wqes - 1 ); 01333 if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) { 01334 DBGC ( hermon, "Hermon %p send queue full", hermon ); 01335 return -ENOBUFS; 01336 } 01337 wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf; 01338 wqe = &hermon_send_wq->wqe[ wq->next_idx & 01339 ( hermon_send_wq->num_wqes - 1 ) ]; 01340 01341 /* Construct work queue entry */ 01342 memset ( ( ( ( void * ) wqe ) + 4 /* avoid ctrl.owner */ ), 0, 01343 ( sizeof ( *wqe ) - 4 ) ); 01344 assert ( qp->type < ( sizeof ( hermon_fill_send_wqe ) / 01345 sizeof ( hermon_fill_send_wqe[0] ) ) ); 01346 assert ( hermon_fill_send_wqe[qp->type] != NULL ); 01347 opcode = hermon_fill_send_wqe[qp->type] ( ibdev, qp, av, iobuf, wqe ); 01348 barrier(); 01349 MLX_FILL_2 ( &wqe->ctrl, 0, 01350 opcode, opcode, 01351 owner, 01352 ( ( wq->next_idx & hermon_send_wq->num_wqes ) ? 1 : 0 ) ); 01353 DBGCP ( hermon, "Hermon %p posting send WQE:\n", hermon ); 01354 DBGCP_HD ( hermon, wqe, sizeof ( *wqe ) ); 01355 barrier(); 01356 01357 /* Ring doorbell register */ 01358 MLX_FILL_1 ( &db_reg.send, 0, qn, qp->qpn ); 01359 DBGCP ( hermon, "Ringing doorbell %08lx with %08x\n", 01360 virt_to_phys ( hermon_send_wq->doorbell ), db_reg.dword[0] ); 01361 writel ( db_reg.dword[0], ( hermon_send_wq->doorbell ) ); 01362 01363 /* Update work queue's index */ 01364 wq->next_idx++; 01365 01366 return 0; 01367 }
| static int hermon_post_recv | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp, | |||
| struct io_buffer * | iobuf | |||
| ) | [static] |
Post receive work queue entry.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| iobuf | I/O buffer |
| rc | Return status code |
Definition at line 1377 of file hermon.c.
References barrier, io_buffer::data, hermonprm_recv_wqe::data, DBGC, ENOBUFS, ib_get_drvdata(), ib_qp_get_drvdata(), iob_tailroom(), ib_work_queue::iobufs, hermon::lkey, MLX_FILL_1, ib_work_queue::next_idx, ib_work_queue::num_wqes, hermon_recv_wqe::recv, hermon_queue_pair::recv, ib_queue_pair::recv, virt_to_bus(), and hermon_recv_work_queue::wqe.
01379 { 01380 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01381 struct hermon_queue_pair *hermon_qp = ib_qp_get_drvdata ( qp ); 01382 struct ib_work_queue *wq = &qp->recv; 01383 struct hermon_recv_work_queue *hermon_recv_wq = &hermon_qp->recv; 01384 struct hermonprm_recv_wqe *wqe; 01385 unsigned int wqe_idx_mask; 01386 01387 /* Allocate work queue entry */ 01388 wqe_idx_mask = ( wq->num_wqes - 1 ); 01389 if ( wq->iobufs[wq->next_idx & wqe_idx_mask] ) { 01390 DBGC ( hermon, "Hermon %p receive queue full", hermon ); 01391 return -ENOBUFS; 01392 } 01393 wq->iobufs[wq->next_idx & wqe_idx_mask] = iobuf; 01394 wqe = &hermon_recv_wq->wqe[wq->next_idx & wqe_idx_mask].recv; 01395 01396 /* Construct work queue entry */ 01397 MLX_FILL_1 ( &wqe->data[0], 0, byte_count, iob_tailroom ( iobuf ) ); 01398 MLX_FILL_1 ( &wqe->data[0], 1, l_key, hermon->lkey ); 01399 MLX_FILL_1 ( &wqe->data[0], 3, 01400 local_address_l, virt_to_bus ( iobuf->data ) ); 01401 01402 /* Update work queue's index */ 01403 wq->next_idx++; 01404 01405 /* Update doorbell record */ 01406 barrier(); 01407 MLX_FILL_1 ( &hermon_recv_wq->doorbell, 0, receive_wqe_counter, 01408 ( wq->next_idx & 0xffff ) ); 01409 01410 return 0; 01411 }
| static int hermon_complete | ( | struct ib_device * | ibdev, | |
| struct ib_completion_queue * | cq, | |||
| union hermonprm_completion_entry * | cqe | |||
| ) | [static] |
Handle completion.
| ibdev | Infiniband device | |
| cq | Completion queue | |
| cqe | Hardware completion queue entry |
| rc | Return status code |
Definition at line 1421 of file hermon.c.
References assert, ib_queue_pair::av, ib_completion_queue::cqn, io_buffer::data, DBGC, EINVAL, EIO, hermonprm_completion_entry::error, ib_address_vector::gid, ib_address_vector::gid_present, HERMON_OPCODE_RECV_ERROR, HERMON_OPCODE_SEND_ERROR, ib_complete_recv(), ib_complete_send(), ib_find_wq(), ib_get_drvdata(), ib_qp_get_drvdata(), IB_QPT_GSI, IB_QPT_RC, IB_QPT_SMI, IB_QPT_UD, iob_len(), iob_pull, iob_put, iob_tailroom(), ib_work_queue::iobufs, ib_address_vector::lid, memcpy, memset(), MLX_GET, hermonprm_completion_entry::normal, NULL, ib_work_queue::num_wqes, ib_work_queue::qp, ib_queue_pair::qpn, ib_address_vector::qpn, ib_global_route_header::sgid, ib_address_vector::sl, and ib_queue_pair::type.
Referenced by hermon_poll_cq().
01423 { 01424 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01425 struct ib_work_queue *wq; 01426 struct ib_queue_pair *qp; 01427 struct hermon_queue_pair *hermon_qp; 01428 struct io_buffer *iobuf; 01429 struct ib_address_vector recv_av; 01430 struct ib_global_route_header *grh; 01431 struct ib_address_vector *av; 01432 unsigned int opcode; 01433 unsigned long qpn; 01434 int is_send; 01435 unsigned int wqe_idx; 01436 size_t len; 01437 int rc = 0; 01438 01439 /* Parse completion */ 01440 qpn = MLX_GET ( &cqe->normal, qpn ); 01441 is_send = MLX_GET ( &cqe->normal, s_r ); 01442 opcode = MLX_GET ( &cqe->normal, opcode ); 01443 if ( opcode >= HERMON_OPCODE_RECV_ERROR ) { 01444 /* "s" field is not valid for error opcodes */ 01445 is_send = ( opcode == HERMON_OPCODE_SEND_ERROR ); 01446 DBGC ( hermon, "Hermon %p CQN %lx syndrome %x vendor %x\n", 01447 hermon, cq->cqn, MLX_GET ( &cqe->error, syndrome ), 01448 MLX_GET ( &cqe->error, vendor_error_syndrome ) ); 01449 rc = -EIO; 01450 /* Don't return immediately; propagate error to completer */ 01451 } 01452 01453 /* Identify work queue */ 01454 wq = ib_find_wq ( cq, qpn, is_send ); 01455 if ( ! wq ) { 01456 DBGC ( hermon, "Hermon %p CQN %lx unknown %s QPN %lx\n", 01457 hermon, cq->cqn, ( is_send ? "send" : "recv" ), qpn ); 01458 return -EIO; 01459 } 01460 qp = wq->qp; 01461 hermon_qp = ib_qp_get_drvdata ( qp ); 01462 01463 /* Identify I/O buffer */ 01464 wqe_idx = ( MLX_GET ( &cqe->normal, wqe_counter ) & 01465 ( wq->num_wqes - 1 ) ); 01466 iobuf = wq->iobufs[wqe_idx]; 01467 if ( ! iobuf ) { 01468 DBGC ( hermon, "Hermon %p CQN %lx QPN %lx empty WQE %x\n", 01469 hermon, cq->cqn, qp->qpn, wqe_idx ); 01470 return -EIO; 01471 } 01472 wq->iobufs[wqe_idx] = NULL; 01473 01474 if ( is_send ) { 01475 /* Hand off to completion handler */ 01476 ib_complete_send ( ibdev, qp, iobuf, rc ); 01477 } else { 01478 /* Set received length */ 01479 len = MLX_GET ( &cqe->normal, byte_cnt ); 01480 assert ( len <= iob_tailroom ( iobuf ) ); 01481 iob_put ( iobuf, len ); 01482 switch ( qp->type ) { 01483 case IB_QPT_SMI: 01484 case IB_QPT_GSI: 01485 case IB_QPT_UD: 01486 assert ( iob_len ( iobuf ) >= sizeof ( *grh ) ); 01487 grh = iobuf->data; 01488 iob_pull ( iobuf, sizeof ( *grh ) ); 01489 /* Construct address vector */ 01490 av = &recv_av; 01491 memset ( av, 0, sizeof ( *av ) ); 01492 av->qpn = MLX_GET ( &cqe->normal, srq_rqpn ); 01493 av->lid = MLX_GET ( &cqe->normal, slid_smac47_32 ); 01494 av->sl = MLX_GET ( &cqe->normal, sl ); 01495 av->gid_present = MLX_GET ( &cqe->normal, g ); 01496 memcpy ( &av->gid, &grh->sgid, sizeof ( av->gid ) ); 01497 break; 01498 case IB_QPT_RC: 01499 av = &qp->av; 01500 break; 01501 default: 01502 assert ( 0 ); 01503 return -EINVAL; 01504 } 01505 /* Hand off to completion handler */ 01506 ib_complete_recv ( ibdev, qp, av, iobuf, rc ); 01507 } 01508 01509 return rc; 01510 }
| static void hermon_poll_cq | ( | struct ib_device * | ibdev, | |
| struct ib_completion_queue * | cq | |||
| ) | [static] |
Poll completion queue.
| ibdev | Infiniband device | |
| cq | Completion queue |
Definition at line 1518 of file hermon.c.
References hermon_completion_queue::cqe, DBGC, DBGC_HD, DBGCP, DBGCP_HD, hermon_complete(), ib_cq_get_drvdata(), ib_get_drvdata(), MLX_FILL_1, MLX_GET, ib_completion_queue::next_idx, hermonprm_completion_entry::normal, ib_completion_queue::num_cqes, and strerror().
01519 { 01520 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01521 struct hermon_completion_queue *hermon_cq = ib_cq_get_drvdata ( cq ); 01522 union hermonprm_completion_entry *cqe; 01523 unsigned int cqe_idx_mask; 01524 int rc; 01525 01526 while ( 1 ) { 01527 /* Look for completion entry */ 01528 cqe_idx_mask = ( cq->num_cqes - 1 ); 01529 cqe = &hermon_cq->cqe[cq->next_idx & cqe_idx_mask]; 01530 if ( MLX_GET ( &cqe->normal, owner ) ^ 01531 ( ( cq->next_idx & cq->num_cqes ) ? 1 : 0 ) ) { 01532 /* Entry still owned by hardware; end of poll */ 01533 break; 01534 } 01535 DBGCP ( hermon, "Hermon %p completion:\n", hermon ); 01536 DBGCP_HD ( hermon, cqe, sizeof ( *cqe ) ); 01537 01538 /* Handle completion */ 01539 if ( ( rc = hermon_complete ( ibdev, cq, cqe ) ) != 0 ) { 01540 DBGC ( hermon, "Hermon %p failed to complete: %s\n", 01541 hermon, strerror ( rc ) ); 01542 DBGC_HD ( hermon, cqe, sizeof ( *cqe ) ); 01543 } 01544 01545 /* Update completion queue's index */ 01546 cq->next_idx++; 01547 01548 /* Update doorbell record */ 01549 MLX_FILL_1 ( &hermon_cq->doorbell, 0, update_ci, 01550 ( cq->next_idx & 0x00ffffffUL ) ); 01551 } 01552 }
| static int hermon_create_eq | ( | struct hermon * | hermon | ) | [static] |
Create event queue.
| rc | Return status code |
Definition at line 1567 of file hermon.c.
References barrier, hermon::cap, DBGC, hermon_event_queue::doorbell, ENOMEM, hermon::eq, hermon_event_queue::eqe, hermon_event_queue::eqe_size, hermon_event_queue::eqn, fls, free_dma(), hermonprm_event_entry::generic, hermon_alloc_mtt(), hermon_cmd_hw2sw_eq(), hermon_cmd_map_eq(), hermon_cmd_sw2hw_eq(), HERMON_DB_EQ_OFFSET, hermon_free_mtt(), HERMON_MAP_EQ, HERMON_NUM_EQES, malloc_dma(), memset(), MLX_FILL_1, hermon_event_queue::mtt, hermon_mtt::mtt_base_addr, hermon_mtt::page_offset, hermon_dev_cap::reserved_eqs, hermon_dev_cap::reserved_uars, strerror(), and hermon::uar.
Referenced by hermon_probe().
01567 { 01568 struct hermon_event_queue *hermon_eq = &hermon->eq; 01569 struct hermonprm_eqc eqctx; 01570 struct hermonprm_event_mask mask; 01571 unsigned int i; 01572 int rc; 01573 01574 /* Select event queue number */ 01575 hermon_eq->eqn = ( 4 * hermon->cap.reserved_uars ); 01576 if ( hermon_eq->eqn < hermon->cap.reserved_eqs ) 01577 hermon_eq->eqn = hermon->cap.reserved_eqs; 01578 01579 /* Calculate doorbell address */ 01580 hermon_eq->doorbell = 01581 ( hermon->uar + HERMON_DB_EQ_OFFSET ( hermon_eq->eqn ) ); 01582 01583 /* Allocate event queue itself */ 01584 hermon_eq->eqe_size = 01585 ( HERMON_NUM_EQES * sizeof ( hermon_eq->eqe[0] ) ); 01586 hermon_eq->eqe = malloc_dma ( hermon_eq->eqe_size, 01587 sizeof ( hermon_eq->eqe[0] ) ); 01588 if ( ! hermon_eq->eqe ) { 01589 rc = -ENOMEM; 01590 goto err_eqe; 01591 } 01592 memset ( hermon_eq->eqe, 0, hermon_eq->eqe_size ); 01593 for ( i = 0 ; i < HERMON_NUM_EQES ; i++ ) { 01594 MLX_FILL_1 ( &hermon_eq->eqe[i].generic, 7, owner, 1 ); 01595 } 01596 barrier(); 01597 01598 /* Allocate MTT entries */ 01599 if ( ( rc = hermon_alloc_mtt ( hermon, hermon_eq->eqe, 01600 hermon_eq->eqe_size, 01601 &hermon_eq->mtt ) ) != 0 ) 01602 goto err_alloc_mtt; 01603 01604 /* Hand queue over to hardware */ 01605 memset ( &eqctx, 0, sizeof ( eqctx ) ); 01606 MLX_FILL_1 ( &eqctx, 0, st, 0xa /* "Fired" */ ); 01607 MLX_FILL_1 ( &eqctx, 2, 01608 page_offset, ( hermon_eq->mtt.page_offset >> 5 ) ); 01609 MLX_FILL_1 ( &eqctx, 3, log_eq_size, fls ( HERMON_NUM_EQES - 1 ) ); 01610 MLX_FILL_1 ( &eqctx, 7, mtt_base_addr_l, 01611 ( hermon_eq->mtt.mtt_base_addr >> 3 ) ); 01612 if ( ( rc = hermon_cmd_sw2hw_eq ( hermon, hermon_eq->eqn, 01613 &eqctx ) ) != 0 ) { 01614 DBGC ( hermon, "Hermon %p SW2HW_EQ failed: %s\n", 01615 hermon, strerror ( rc ) ); 01616 goto err_sw2hw_eq; 01617 } 01618 01619 /* Map events to this event queue */ 01620 memset ( &mask, 0, sizeof ( mask ) ); 01621 MLX_FILL_1 ( &mask, 1, port_state_change, 1 ); 01622 if ( ( rc = hermon_cmd_map_eq ( hermon, 01623 ( HERMON_MAP_EQ | hermon_eq->eqn ), 01624 &mask ) ) != 0 ) { 01625 DBGC ( hermon, "Hermon %p MAP_EQ failed: %s\n", 01626 hermon, strerror ( rc ) ); 01627 goto err_map_eq; 01628 } 01629 01630 DBGC ( hermon, "Hermon %p EQN %#lx ring at [%p,%p])\n", 01631 hermon, hermon_eq->eqn, hermon_eq->eqe, 01632 ( ( ( void * ) hermon_eq->eqe ) + hermon_eq->eqe_size ) ); 01633 return 0; 01634 01635 err_map_eq: 01636 hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn, &eqctx ); 01637 err_sw2hw_eq: 01638 hermon_free_mtt ( hermon, &hermon_eq->mtt ); 01639 err_alloc_mtt: 01640 free_dma ( hermon_eq->eqe, hermon_eq->eqe_size ); 01641 err_eqe: 01642 memset ( hermon_eq, 0, sizeof ( *hermon_eq ) ); 01643 return rc; 01644 }
| static void hermon_destroy_eq | ( | struct hermon * | hermon | ) | [static] |
Destroy event queue.
Definition at line 1651 of file hermon.c.
References DBGC, hermon::eq, hermon_event_queue::eqe, hermon_event_queue::eqe_size, hermon_event_queue::eqn, free_dma(), hermon_cmd_hw2sw_eq(), hermon_cmd_map_eq(), hermon_free_mtt(), HERMON_UNMAP_EQ, memset(), MLX_FILL_1, hermon_event_queue::mtt, and strerror().
Referenced by hermon_probe(), and hermon_remove().
01651 { 01652 struct hermon_event_queue *hermon_eq = &hermon->eq; 01653 struct hermonprm_eqc eqctx; 01654 struct hermonprm_event_mask mask; 01655 int rc; 01656 01657 /* Unmap events from event queue */ 01658 memset ( &mask, 0, sizeof ( mask ) ); 01659 MLX_FILL_1 ( &mask, 1, port_state_change, 1 ); 01660 if ( ( rc = hermon_cmd_map_eq ( hermon, 01661 ( HERMON_UNMAP_EQ | hermon_eq->eqn ), 01662 &mask ) ) != 0 ) { 01663 DBGC ( hermon, "Hermon %p FATAL MAP_EQ failed to unmap: %s\n", 01664 hermon, strerror ( rc ) ); 01665 /* Continue; HCA may die but system should survive */ 01666 } 01667 01668 /* Take ownership back from hardware */ 01669 if ( ( rc = hermon_cmd_hw2sw_eq ( hermon, hermon_eq->eqn, 01670 &eqctx ) ) != 0 ) { 01671 DBGC ( hermon, "Hermon %p FATAL HW2SW_EQ failed: %s\n", 01672 hermon, strerror ( rc ) ); 01673 /* Leak memory and return; at least we avoid corruption */ 01674 return; 01675 } 01676 01677 /* Free MTT entries */ 01678 hermon_free_mtt ( hermon, &hermon_eq->mtt ); 01679 01680 /* Free memory */ 01681 free_dma ( hermon_eq->eqe, hermon_eq->eqe_size ); 01682 memset ( hermon_eq, 0, sizeof ( *hermon_eq ) ); 01683 }
| static void hermon_event_port_state_change | ( | struct hermon * | hermon, | |
| union hermonprm_event_entry * | eqe | |||
| ) | [static] |
Handle port state event.
Definition at line 1691 of file hermon.c.
References hermon::cap, DBGC, hermonprm_event_entry::generic, hermon_mad(), ib_link_state_changed(), ib_smc_update(), hermon::ibdev, MLX_GET, hermon_dev_cap::num_ports, and hermonprm_event_entry::port_state_change.
Referenced by hermon_poll_eq().
01692 { 01693 unsigned int port; 01694 int link_up; 01695 01696 /* Get port and link status */ 01697 port = ( MLX_GET ( &eqe->port_state_change, data.p ) - 1 ); 01698 link_up = ( MLX_GET ( &eqe->generic, event_sub_type ) & 0x04 ); 01699 DBGC ( hermon, "Hermon %p port %d link %s\n", hermon, ( port + 1 ), 01700 ( link_up ? "up" : "down" ) ); 01701 01702 /* Sanity check */ 01703 if ( port >= hermon->cap.num_ports ) { 01704 DBGC ( hermon, "Hermon %p port %d does not exist!\n", 01705 hermon, ( port + 1 ) ); 01706 return; 01707 } 01708 01709 /* Update MAD parameters */ 01710 ib_smc_update ( hermon->ibdev[port], hermon_mad ); 01711 01712 /* Notify Infiniband core of link state change */ 01713 ib_link_state_changed ( hermon->ibdev[port] ); 01714 }
| static void hermon_poll_eq | ( | struct ib_device * | ibdev | ) | [static] |
Poll event queue.
| ibdev | Infiniband device |
Definition at line 1721 of file hermon.c.
References DBGC, DBGC_HD, DBGCP, DBGCP_HD, hermon_event_queue::doorbell, hermonprm_doorbell_register::dword, hermon::eq, hermon_event_queue::eqe, hermonprm_doorbell_register::event, hermonprm_event_entry::generic, HERMON_EV_PORT_STATE_CHANGE, hermon_event_port_state_change(), HERMON_NUM_EQES, ib_get_drvdata(), MLX_FILL_1, MLX_GET, hermon_event_queue::next_idx, virt_to_phys(), and writel.
01721 { 01722 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01723 struct hermon_event_queue *hermon_eq = &hermon->eq; 01724 union hermonprm_event_entry *eqe; 01725 union hermonprm_doorbell_register db_reg; 01726 unsigned int eqe_idx_mask; 01727 unsigned int event_type; 01728 01729 while ( 1 ) { 01730 /* Look for event entry */ 01731 eqe_idx_mask = ( HERMON_NUM_EQES - 1 ); 01732 eqe = &hermon_eq->eqe[hermon_eq->next_idx & eqe_idx_mask]; 01733 if ( MLX_GET ( &eqe->generic, owner ) ^ 01734 ( ( hermon_eq->next_idx & HERMON_NUM_EQES ) ? 1 : 0 ) ) { 01735 /* Entry still owned by hardware; end of poll */ 01736 break; 01737 } 01738 DBGCP ( hermon, "Hermon %p event:\n", hermon ); 01739 DBGCP_HD ( hermon, eqe, sizeof ( *eqe ) ); 01740 01741 /* Handle event */ 01742 event_type = MLX_GET ( &eqe->generic, event_type ); 01743 switch ( event_type ) { 01744 case HERMON_EV_PORT_STATE_CHANGE: 01745 hermon_event_port_state_change ( hermon, eqe ); 01746 break; 01747 default: 01748 DBGC ( hermon, "Hermon %p unrecognised event type " 01749 "%#x:\n", hermon, event_type ); 01750 DBGC_HD ( hermon, eqe, sizeof ( *eqe ) ); 01751 break; 01752 } 01753 01754 /* Update event queue's index */ 01755 hermon_eq->next_idx++; 01756 01757 /* Ring doorbell */ 01758 MLX_FILL_1 ( &db_reg.event, 0, 01759 ci, ( hermon_eq->next_idx & 0x00ffffffUL ) ); 01760 DBGCP ( hermon, "Ringing doorbell %08lx with %08x\n", 01761 virt_to_phys ( hermon_eq->doorbell ), 01762 db_reg.dword[0] ); 01763 writel ( db_reg.dword[0], hermon_eq->doorbell ); 01764 } 01765 }
| static int hermon_sense_port_type | ( | struct ib_device * | ibdev | ) | [static] |
Sense port type.
| ibdev | Infiniband device |
| port_type | Port type, or negative error |
Definition at line 1780 of file hermon.c.
References hermon::cap, DBGC, hermon_dev_cap::dpdp, hermon_cmd_sense_port(), HERMON_PORT_TYPE_IB, ib_get_drvdata(), MLX_GET, ib_device::port, and strerror().
Referenced by hermon_open().
01780 { 01781 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01782 struct hermonprm_sense_port sense_port; 01783 int port_type; 01784 int rc; 01785 01786 /* If DPDP is not supported, always assume Infiniband */ 01787 if ( ! hermon->cap.dpdp ) 01788 return HERMON_PORT_TYPE_IB; 01789 01790 /* Sense the port type */ 01791 if ( ( rc = hermon_cmd_sense_port ( hermon, ibdev->port, 01792 &sense_port ) ) != 0 ) { 01793 DBGC ( hermon, "Hermon %p port %d sense failed: %s\n", 01794 hermon, ibdev->port, strerror ( rc ) ); 01795 return rc; 01796 } 01797 port_type = MLX_GET ( &sense_port, port_type ); 01798 01799 DBGC ( hermon, "Hermon %p port %d type %d\n", 01800 hermon, ibdev->port, port_type ); 01801 return port_type; 01802 }
| static int hermon_open | ( | struct ib_device * | ibdev | ) | [static] |
Initialise Infiniband link.
| ibdev | Infiniband device |
| rc | Return status code |
Definition at line 1810 of file hermon.c.
References DBGC, ENOTCONN, hermon_cmd_init_port(), hermon_mad(), HERMON_MTU_2048, HERMON_PORT_TYPE_IB, hermon_sense_port_type(), ib_get_drvdata(), ib_smc_update(), memset(), MLX_FILL_1, MLX_FILL_2, mtu, ib_device::port, and strerror().
01810 { 01811 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01812 struct hermonprm_init_port init_port; 01813 int port_type; 01814 int rc; 01815 01816 /* Check we are connected to an Infiniband network */ 01817 if ( ( rc = port_type = hermon_sense_port_type ( ibdev ) ) < 0 ) 01818 return rc; 01819 if ( port_type != HERMON_PORT_TYPE_IB ) { 01820 DBGC ( hermon, "Hermon %p port %d not connected to an " 01821 "Infiniband network", hermon, ibdev->port ); 01822 return -ENOTCONN; 01823 } 01824 01825 /* Init Port */ 01826 memset ( &init_port, 0, sizeof ( init_port ) ); 01827 MLX_FILL_2 ( &init_port, 0, 01828 port_width_cap, 3, 01829 vl_cap, 1 ); 01830 MLX_FILL_2 ( &init_port, 1, 01831 mtu, HERMON_MTU_2048, 01832 max_gid, 1 ); 01833 MLX_FILL_1 ( &init_port, 2, max_pkey, 64 ); 01834 if ( ( rc = hermon_cmd_init_port ( hermon, ibdev->port, 01835 &init_port ) ) != 0 ) { 01836 DBGC ( hermon, "Hermon %p could not intialise port: %s\n", 01837 hermon, strerror ( rc ) ); 01838 return rc; 01839 } 01840 01841 /* Update MAD parameters */ 01842 ib_smc_update ( ibdev, hermon_mad ); 01843 01844 return 0; 01845 }
| static void hermon_close | ( | struct ib_device * | ibdev | ) | [static] |
Close Infiniband link.
| ibdev | Infiniband device |
Definition at line 1852 of file hermon.c.
References DBGC, hermon_cmd_close_port(), ib_get_drvdata(), ib_device::port, and strerror().
01852 { 01853 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01854 int rc; 01855 01856 if ( ( rc = hermon_cmd_close_port ( hermon, ibdev->port ) ) != 0 ) { 01857 DBGC ( hermon, "Hermon %p could not close port: %s\n", 01858 hermon, strerror ( rc ) ); 01859 /* Nothing we can do about this */ 01860 } 01861 }
Inform embedded subnet management agent of a received MAD.
| ibdev | Infiniband device | |
| mad | MAD |
| rc | Return status code |
Definition at line 1870 of file hermon.c.
References hermon_mad(), and ib_smc_update().
01871 { 01872 int rc; 01873 01874 /* Send the MAD to the embedded SMA */ 01875 if ( ( rc = hermon_mad ( ibdev, mad ) ) != 0 ) 01876 return rc; 01877 01878 /* Update parameters held in software */ 01879 ib_smc_update ( ibdev, hermon_mad ); 01880 01881 return 0; 01882 }
| static int hermon_mcast_attach | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair * | qp, | |||
| struct ib_gid * | gid | |||
| ) | [static] |
Attach to multicast group.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| gid | Multicast GID |
| rc | Return status code |
Definition at line 1899 of file hermon.c.
References DBGC, EBUSY, hermon_cmd_mgid_hash(), hermon_cmd_read_mcg(), hermon_cmd_write_mcg(), ib_get_drvdata(), index, memcpy, MLX_FILL_1, MLX_GET, ib_queue_pair::qpn, and strerror().
01901 { 01902 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01903 struct hermonprm_mgm_hash hash; 01904 struct hermonprm_mcg_entry mcg; 01905 unsigned int index; 01906 int rc; 01907 01908 /* Generate hash table index */ 01909 if ( ( rc = hermon_cmd_mgid_hash ( hermon, gid, &hash ) ) != 0 ) { 01910 DBGC ( hermon, "Hermon %p could not hash GID: %s\n", 01911 hermon, strerror ( rc ) ); 01912 return rc; 01913 } 01914 index = MLX_GET ( &hash, hash ); 01915 01916 /* Check for existing hash table entry */ 01917 if ( ( rc = hermon_cmd_read_mcg ( hermon, index, &mcg ) ) != 0 ) { 01918 DBGC ( hermon, "Hermon %p could not read MCG %#x: %s\n", 01919 hermon, index, strerror ( rc ) ); 01920 return rc; 01921 } 01922 if ( MLX_GET ( &mcg, hdr.members_count ) != 0 ) { 01923 /* FIXME: this implementation allows only a single QP 01924 * per multicast group, and doesn't handle hash 01925 * collisions. Sufficient for IPoIB but may need to 01926 * be extended in future. 01927 */ 01928 DBGC ( hermon, "Hermon %p MGID index %#x already in use\n", 01929 hermon, index ); 01930 return -EBUSY; 01931 } 01932 01933 /* Update hash table entry */ 01934 MLX_FILL_1 ( &mcg, 1, hdr.members_count, 1 ); 01935 MLX_FILL_1 ( &mcg, 8, qp[0].qpn, qp->qpn ); 01936 memcpy ( &mcg.u.dwords[4], gid, sizeof ( *gid ) ); 01937 if ( ( rc = hermon_cmd_write_mcg ( hermon, index, &mcg ) ) != 0 ) { 01938 DBGC ( hermon, "Hermon %p could not write MCG %#x: %s\n", 01939 hermon, index, strerror ( rc ) ); 01940 return rc; 01941 } 01942 01943 return 0; 01944 }
| static void hermon_mcast_detach | ( | struct ib_device * | ibdev, | |
| struct ib_queue_pair *qp | __unused, | |||
| struct ib_gid * | gid | |||
| ) | [static] |
Detach from multicast group.
| ibdev | Infiniband device | |
| qp | Queue pair | |
| gid | Multicast GID |
Definition at line 1953 of file hermon.c.
References DBGC, hermon_cmd_mgid_hash(), hermon_cmd_write_mcg(), ib_get_drvdata(), index, memset(), MLX_GET, and strerror().
01955 { 01956 struct hermon *hermon = ib_get_drvdata ( ibdev ); 01957 struct hermonprm_mgm_hash hash; 01958 struct hermonprm_mcg_entry mcg; 01959 unsigned int index; 01960 int rc; 01961 01962 /* Generate hash table index */ 01963 if ( ( rc = hermon_cmd_mgid_hash ( hermon, gid, &hash ) ) != 0 ) { 01964 DBGC ( hermon, "Hermon %p could not hash GID: %s\n", 01965 hermon, strerror ( rc ) ); 01966 return; 01967 } 01968 index = MLX_GET ( &hash, hash ); 01969 01970 /* Clear hash table entry */ 01971 memset ( &mcg, 0, sizeof ( mcg ) ); 01972 if ( ( rc = hermon_cmd_write_mcg ( hermon, index, &mcg ) ) != 0 ) { 01973 DBGC ( hermon, "Hermon %p could not write MCG %#x: %s\n", 01974 hermon, index, strerror ( rc ) ); 01975 return; 01976 } 01977 }
| static int hermon_map_vpm | ( | struct hermon * | hermon, | |
| int(*)(struct hermon *hermon, const struct hermonprm_virtual_physical_mapping *) | map, | |||
| uint64_t | va, | |||
| physaddr_t | pa, | |||
| size_t | len | |||
| ) | [static] |
Map virtual to physical address for firmware usage.
| hermon | Hermon device | |
| map | Mapping function | |
| va | Virtual address | |
| pa | Physical address | |
| len | Length of region |
| rc | Return status code |
Definition at line 2015 of file hermon.c.
References assert, DBG_DISABLE, DBG_ENABLE, DBGC, DBGLVL_EXTRA, DBGLVL_LOG, HERMON_PAGE_SIZE, memset(), MLX_FILL_1, MLX_FILL_2, and strerror().
Referenced by hermon_alloc_icm(), and hermon_start_firmware().
02018 { 02019 struct hermonprm_virtual_physical_mapping mapping; 02020 int rc; 02021 02022 assert ( ( va & ( HERMON_PAGE_SIZE - 1 ) ) == 0 ); 02023 assert ( ( pa & ( HERMON_PAGE_SIZE - 1 ) ) == 0 ); 02024 assert ( ( len & ( HERMON_PAGE_SIZE - 1 ) ) == 0 ); 02025 02026 /* These mappings tend to generate huge volumes of 02027 * uninteresting debug data, which basically makes it 02028 * impossible to use debugging otherwise. 02029 */ 02030 DBG_DISABLE ( DBGLVL_LOG | DBGLVL_EXTRA ); 02031 02032 while ( len ) { 02033 memset ( &mapping, 0, sizeof ( mapping ) ); 02034 MLX_FILL_1 ( &mapping, 0, va_h, ( va >> 32 ) ); 02035 MLX_FILL_1 ( &mapping, 1, va_l, ( va >> 12 ) ); 02036 MLX_FILL_2 ( &mapping, 3, 02037 log2size, 0, 02038 pa_l, ( pa >> 12 ) ); 02039 if ( ( rc = map ( hermon, &mapping ) ) != 0 ) { 02040 DBG_ENABLE ( DBGLVL_LOG | DBGLVL_EXTRA ); 02041 DBGC ( hermon, "Hermon %p could not map %llx => %lx: " 02042 "%s\n", hermon, va, pa, strerror ( rc ) ); 02043 return rc; 02044 } 02045 pa += HERMON_PAGE_SIZE; 02046 va += HERMON_PAGE_SIZE; 02047 len -= HERMON_PAGE_SIZE; 02048 } 02049 02050 DBG_ENABLE ( DBGLVL_LOG | DBGLVL_EXTRA ); 02051 return 0; 02052 }
| static int hermon_start_firmware | ( | struct hermon * | hermon | ) | [static] |
Start firmware running.
| rc | Return status code |
Definition at line 2060 of file hermon.c.
References DBGC, ENOMEM, hermon::firmware_area, hermon_cmd_map_fa(), hermon_cmd_query_fw(), hermon_cmd_run_fw(), hermon_cmd_unmap_fa(), hermon_map_vpm(), HERMON_PAGE_SIZE, MLX_GET, strerror(), ufree(), umalloc(), UNULL, and user_to_phys().
Referenced by hermon_probe().
02060 { 02061 struct hermonprm_query_fw fw; 02062 unsigned int fw_pages; 02063 size_t fw_size; 02064 physaddr_t fw_base; 02065 int rc; 02066 02067 /* Get firmware parameters */ 02068 if ( ( rc = hermon_cmd_query_fw ( hermon, &fw ) ) != 0 ) { 02069 DBGC ( hermon, "Hermon %p could not query firmware: %s\n", 02070 hermon, strerror ( rc ) ); 02071 goto err_query_fw; 02072 } 02073 DBGC ( hermon, "Hermon %p firmware version %d.%d.%d\n", hermon, 02074 MLX_GET ( &fw, fw_rev_major ), MLX_GET ( &fw, fw_rev_minor ), 02075 MLX_GET ( &fw, fw_rev_subminor ) ); 02076 fw_pages = MLX_GET ( &fw, fw_pages ); 02077 DBGC ( hermon, "Hermon %p requires %d pages (%d kB) for firmware\n", 02078 hermon, fw_pages, ( fw_pages * ( HERMON_PAGE_SIZE / 1024 ) ) ); 02079 02080 /* Allocate firmware pages and map firmware area */ 02081 fw_size = ( fw_pages * HERMON_PAGE_SIZE ); 02082 hermon->firmware_area = umalloc ( fw_size ); 02083 if ( ! hermon->firmware_area ) { 02084 rc = -ENOMEM; 02085 goto err_alloc_fa; 02086 } 02087 fw_base = user_to_phys ( hermon->firmware_area, 0 ); 02088 DBGC ( hermon, "Hermon %p firmware area at physical [%lx,%lx)\n", 02089 hermon, fw_base, ( fw_base + fw_size ) ); 02090 if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_fa, 02091 0, fw_base, fw_size ) ) != 0 ) { 02092 DBGC ( hermon, "Hermon %p could not map firmware: %s\n", 02093 hermon, strerror ( rc ) ); 02094 goto err_map_fa; 02095 } 02096 02097 /* Start firmware */ 02098 if ( ( rc = hermon_cmd_run_fw ( hermon ) ) != 0 ) { 02099 DBGC ( hermon, "Hermon %p could not run firmware: %s\n", 02100 hermon, strerror ( rc ) ); 02101 goto err_run_fw; 02102 } 02103 02104 DBGC ( hermon, "Hermon %p firmware started\n", hermon ); 02105 return 0; 02106 02107 err_run_fw: 02108 err_map_fa: 02109 hermon_cmd_unmap_fa ( hermon ); 02110 ufree ( hermon->firmware_area ); 02111 hermon->firmware_area = UNULL; 02112 err_alloc_fa: 02113 err_query_fw: 02114 return rc; 02115 }
| static void hermon_stop_firmware | ( | struct hermon * | hermon | ) | [static] |
Stop firmware running.
Definition at line 2122 of file hermon.c.
References DBGC, hermon::firmware_area, hermon_cmd_unmap_fa(), strerror(), ufree(), and UNULL.
Referenced by hermon_probe(), and hermon_remove().
02122 { 02123 int rc; 02124 02125 if ( ( rc = hermon_cmd_unmap_fa ( hermon ) ) != 0 ) { 02126 DBGC ( hermon, "Hermon %p FATAL could not stop firmware: %s\n", 02127 hermon, strerror ( rc ) ); 02128 /* Leak memory and return; at least we avoid corruption */ 02129 return; 02130 } 02131 ufree ( hermon->firmware_area ); 02132 hermon->firmware_area = UNULL; 02133 }
| static int hermon_get_cap | ( | struct hermon * | hermon | ) | [static] |
Get device limits.
| rc | Return status code |
Definition at line 2148 of file hermon.c.
References hermon_dev_cap::altc_entry_size, hermon_dev_cap::auxc_entry_size, hermon::cap, hermon_dev_cap::cmpt_entry_size, hermon_dev_cap::cqc_entry_size, DBGC, hermon_dev_cap::dmpt_entry_size, hermon_dev_cap::dpdp, hermon_dev_cap::eqc_entry_size, hermon_cmd_query_dev_cap(), HERMON_MAX_PORTS, MLX_GET, hermon_dev_cap::mtt_entry_size, hermon_dev_cap::num_ports, hermon_dev_cap::qpc_entry_size, hermon_dev_cap::reserved_cqs, hermon_dev_cap::reserved_eqs, hermon_dev_cap::reserved_mrws, hermon_dev_cap::reserved_mtts, hermon_dev_cap::reserved_qps, hermon_dev_cap::reserved_srqs, hermon_dev_cap::reserved_uars, hermon_dev_cap::srqc_entry_size, and strerror().
Referenced by hermon_probe().
02148 { 02149 struct hermonprm_query_dev_cap dev_cap; 02150 int rc; 02151 02152 if ( ( rc = hermon_cmd_query_dev_cap ( hermon, &dev_cap ) ) != 0 ) { 02153 DBGC ( hermon, "Hermon %p could not get device limits: %s\n", 02154 hermon, strerror ( rc ) ); 02155 return rc; 02156 } 02157 02158 hermon->cap.cmpt_entry_size = MLX_GET ( &dev_cap, c_mpt_entry_sz ); 02159 hermon->cap.reserved_qps = 02160 ( 1 << MLX_GET ( &dev_cap, log2_rsvd_qps ) ); 02161 hermon->cap.qpc_entry_size = MLX_GET ( &dev_cap, qpc_entry_sz ); 02162 hermon->cap.altc_entry_size = MLX_GET ( &dev_cap, altc_entry_sz ); 02163 hermon->cap.auxc_entry_size = MLX_GET ( &dev_cap, aux_entry_sz ); 02164 hermon->cap.reserved_srqs = 02165 ( 1 << MLX_GET ( &dev_cap, log2_rsvd_srqs ) ); 02166 hermon->cap.srqc_entry_size = MLX_GET ( &dev_cap, srq_entry_sz ); 02167 hermon->cap.reserved_cqs = 02168 ( 1 << MLX_GET ( &dev_cap, log2_rsvd_cqs ) ); 02169 hermon->cap.cqc_entry_size = MLX_GET ( &dev_cap, cqc_entry_sz ); 02170 hermon->cap.reserved_eqs = MLX_GET ( &dev_cap, num_rsvd_eqs ); 02171 hermon->cap.eqc_entry_size = MLX_GET ( &dev_cap, eqc_entry_sz ); 02172 hermon->cap.reserved_mtts = 02173 ( 1 << MLX_GET ( &dev_cap, log2_rsvd_mtts ) ); 02174 hermon->cap.mtt_entry_size = MLX_GET ( &dev_cap, mtt_entry_sz ); 02175 hermon->cap.reserved_mrws = 02176 ( 1 << MLX_GET ( &dev_cap, log2_rsvd_mrws ) ); 02177 hermon->cap.dmpt_entry_size = MLX_GET ( &dev_cap, d_mpt_entry_sz ); 02178 hermon->cap.reserved_uars = MLX_GET ( &dev_cap, num_rsvd_uars ); 02179 hermon->cap.num_ports = MLX_GET ( &dev_cap, num_ports ); 02180 hermon->cap.dpdp = MLX_GET ( &dev_cap, dpdp ); 02181 02182 /* Sanity check */ 02183 if ( hermon->cap.num_ports > HERMON_MAX_PORTS ) { 02184 DBGC ( hermon, "Hermon %p has %d ports (only %d supported)\n", 02185 hermon, hermon->cap.num_ports, HERMON_MAX_PORTS ); 02186 hermon->cap.num_ports = HERMON_MAX_PORTS; 02187 } 02188 02189 return 0; 02190 }
Get ICM usage.
| log_num_entries | Log2 of the number of entries | |
| entry_size | Entry size |
| usage | Usage size in ICM |
Definition at line 2199 of file hermon.c.
References HERMON_PAGE_SIZE.
02199 { 02200 size_t usage; 02201 02202 usage = ( ( 1 << log_num_entries ) * entry_size ); 02203 usage = ( ( usage + HERMON_PAGE_SIZE - 1 ) & 02204 ~( HERMON_PAGE_SIZE - 1 ) ); 02205 return usage; 02206 }
Align ICM.
| member_size | Member size | |
| cur_icm_offset | Current ICM offset |
| align_offset | Align to offset |
Definition at line 2215 of file hermon.c.
References HERMON_PAGE_SIZE.
Referenced by hermon_alloc_icm().
02216 { 02217 size_t align_offset = 0; 02218 02219 member_size = member_size & 0xfffff000; 02220 if ( member_size ) { 02221 while ( ( cur_icm_offset + align_offset ) % member_size ) { 02222 align_offset += HERMON_PAGE_SIZE; 02223 } 02224 } 02225 02226 return align_offset; 02227 }
| static int hermon_alloc_icm | ( | struct hermon * | hermon, | |
| struct hermonprm_init_hca * | init_hca | |||
| ) | [static] |
Allocate ICM.
| rc | Return status code |
Definition at line 2237 of file hermon.c.
References hermon_dev_cap::altc_entry_size, assert, hermon_dev_cap::auxc_entry_size, hermon::cap, hermon_dev_cap::cmpt_entry_size, hermon_dev_cap::cqc_entry_size, DBGC, hermon_dev_cap::dmpt_entry_size, ENOMEM, hermon_dev_cap::eqc_entry_size, fls, hermon_cmd_map_icm(), hermon_cmd_map_icm_aux(), hermon_cmd_set_icm_size(), hermon_cmd_unmap_icm_aux(), HERMON_CMPT_MAX_ENTRIES, HERMON_ICM_CQ_CMPT, HERMON_ICM_EQ_CMPT, HERMON_ICM_NUM_REGIONS, HERMON_ICM_OTHER, HERMON_ICM_QP_CMPT, HERMON_ICM_SRQ_CMPT, hermon_map_vpm(), HERMON_MAX_CQS, HERMON_MAX_EQS, HERMON_MAX_MTTS, HERMON_MAX_QPS, HERMON_RSVD_SPECIAL_QPS, hermon::icm, icm_align(), hermon::icm_map, icm_usage(), hermon_icm_map::len, memset(), MLX_FILL_1, MLX_FILL_2, MLX_GET, hermon_dev_cap::mtt_entry_size, hermon_icm_map::offset, hermon_dev_cap::qpc_entry_size, hermon_dev_cap::reserved_cqs, hermon_dev_cap::reserved_eqs, hermon_dev_cap::reserved_mrws, hermon_dev_cap::reserved_mtts, hermon_dev_cap::reserved_qps, hermon_dev_cap::reserved_srqs, hermon_dev_cap::srqc_entry_size, strerror(), u32, ufree(), umalloc(), UNULL, and user_to_phys().
Referenced by hermon_probe().
02238 { 02239 struct hermonprm_scalar_parameter icm_size; 02240 struct hermonprm_scalar_parameter icm_aux_size; 02241 uint64_t icm_offset = 0; 02242 u32 icm_member_size = 0; 02243 unsigned int log_num_qps, log_num_srqs, log_num_cqs, log_num_eqs; 02244 unsigned int log_num_mtts, log_num_mpts; 02245 size_t cmpt_max_len; 02246 size_t qp_cmpt_len, srq_cmpt_len, cq_cmpt_len, eq_cmpt_len; 02247 size_t icm_len, icm_aux_len; 02248 physaddr_t icm_phys; 02249 int i; 02250 int rc; 02251 02252 /* 02253 * Start by carving up the ICM virtual address space 02254 * 02255 */ 02256 02257 /* Calculate number of each object type within ICM */ 02258 log_num_qps = fls ( hermon->cap.reserved_qps + 02259 HERMON_RSVD_SPECIAL_QPS + HERMON_MAX_QPS - 1 ); 02260 log_num_srqs = fls ( hermon->cap.reserved_srqs - 1 ); 02261 log_num_cqs = fls ( hermon->cap.reserved_cqs + HERMON_MAX_CQS - 1 ); 02262 log_num_eqs = fls ( hermon->cap.reserved_eqs + HERMON_MAX_EQS - 1 ); 02263 log_num_mtts = fls ( hermon->cap.reserved_mtts + HERMON_MAX_MTTS - 1 ); 02264 02265 /* ICM starts with the cMPT tables, which are sparse */ 02266 cmpt_max_len = ( HERMON_CMPT_MAX_ENTRIES * 02267 ( ( uint64_t ) hermon->cap.cmpt_entry_size ) ); 02268 qp_cmpt_len = icm_usage ( log_num_qps, hermon->cap.cmpt_entry_size ); 02269 hermon->icm_map[HERMON_ICM_QP_CMPT].offset = icm_offset; 02270 hermon->icm_map[HERMON_ICM_QP_CMPT].len = qp_cmpt_len; 02271 icm_offset += cmpt_max_len; 02272 srq_cmpt_len = icm_usage ( log_num_srqs, hermon->cap.cmpt_entry_size ); 02273 hermon->icm_map[HERMON_ICM_SRQ_CMPT].offset = icm_offset; 02274 hermon->icm_map[HERMON_ICM_SRQ_CMPT].len = srq_cmpt_len; 02275 icm_offset += cmpt_max_len; 02276 cq_cmpt_len = icm_usage ( log_num_cqs, hermon->cap.cmpt_entry_size ); 02277 hermon->icm_map[HERMON_ICM_CQ_CMPT].offset = icm_offset; 02278 hermon->icm_map[HERMON_ICM_CQ_CMPT].len = cq_cmpt_len; 02279 icm_offset += cmpt_max_len; 02280 eq_cmpt_len = icm_usage ( log_num_eqs, hermon->cap.cmpt_entry_size ); 02281 hermon->icm_map[HERMON_ICM_EQ_CMPT].offset = icm_offset; 02282 hermon->icm_map[HERMON_ICM_EQ_CMPT].len = eq_cmpt_len; 02283 icm_offset += cmpt_max_len; 02284 02285 hermon->icm_map[HERMON_ICM_OTHER].offset = icm_offset; 02286 02287 /* Queue pair contexts */ 02288 icm_member_size = icm_usage ( log_num_qps, hermon->cap.qpc_entry_size ); 02289 icm_offset += icm_align ( icm_member_size, icm_offset ); 02290 MLX_FILL_1 ( init_hca, 12, 02291 qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_h, 02292 ( icm_offset >> 32 ) ); 02293 MLX_FILL_2 ( init_hca, 13, 02294 qpc_eec_cqc_eqc_rdb_parameters.qpc_base_addr_l, 02295 ( icm_offset >> 5 ), 02296 qpc_eec_cqc_eqc_rdb_parameters.log_num_of_qp, 02297 log_num_qps ); 02298 DBGC ( hermon, "Hermon %p ICM QPC base = %llx\n", hermon, icm_offset ); 02299 icm_offset += icm_member_size; 02300 02301 /* Extended alternate path contexts */ 02302 icm_member_size = icm_usage ( log_num_qps, 02303 hermon->cap.altc_entry_size ); 02304 icm_offset += icm_align ( icm_member_size, icm_offset ); 02305 MLX_FILL_1 ( init_hca, 24, 02306 qpc_eec_cqc_eqc_rdb_parameters.altc_base_addr_h, 02307 ( icm_offset >> 32 ) ); 02308 MLX_FILL_1 ( init_hca, 25, 02309 qpc_eec_cqc_eqc_rdb_parameters.altc_base_addr_l, 02310 icm_offset ); 02311 DBGC ( hermon, "Hermon %p ICM ALTC base = %llx\n", hermon, icm_offset); 02312 icm_offset += icm_member_size; 02313 02314 /* Extended auxiliary contexts */ 02315 icm_member_size = icm_usage ( log_num_qps, 02316 hermon->cap.auxc_entry_size ); 02317 icm_offset += icm_align ( icm_member_size, icm_offset ); 02318 MLX_FILL_1 ( init_hca, 28, 02319 qpc_eec_cqc_eqc_rdb_parameters.auxc_base_addr_h, 02320 ( icm_offset >> 32 ) ); 02321 MLX_FILL_1 ( init_hca, 29, 02322 qpc_eec_cqc_eqc_rdb_parameters.auxc_base_addr_l, 02323 icm_offset ); 02324 DBGC ( hermon, "Hermon %p ICM AUXC base = %llx\n", hermon, icm_offset); 02325 icm_offset += icm_member_size; 02326 /* Shared receive queue contexts */ 02327 icm_member_size = icm_usage ( log_num_srqs, 02328 hermon->cap.srqc_entry_size ); 02329 icm_offset += icm_align ( icm_member_size, icm_offset ); 02330 MLX_FILL_1 ( init_hca, 18, 02331 qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_h, 02332 ( icm_offset >> 32 ) ); 02333 MLX_FILL_2 ( init_hca, 19, 02334 qpc_eec_cqc_eqc_rdb_parameters.srqc_base_addr_l, 02335 ( icm_offset >> 5 ), 02336 qpc_eec_cqc_eqc_rdb_parameters.log_num_of_srq, 02337 log_num_srqs ); 02338 DBGC ( hermon, "Hermon %p ICM SRQC base = %llx\n", hermon, icm_offset); 02339 icm_offset += icm_member_size; 02340 02341 /* Completion queue contexts */ 02342 icm_member_size = icm_usage ( log_num_cqs, hermon->cap.cqc_entry_size ); 02343 icm_offset += icm_align ( icm_member_size, icm_offset ); 02344 MLX_FILL_1 ( init_hca, 20, 02345 qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_h, 02346 ( icm_offset >> 32 ) ); 02347 MLX_FILL_2 ( init_hca, 21, 02348 qpc_eec_cqc_eqc_rdb_parameters.cqc_base_addr_l, 02349 ( icm_offset >> 5 ), 02350 qpc_eec_cqc_eqc_rdb_parameters.log_num_of_cq, 02351 log_num_cqs ); 02352 DBGC ( hermon, "Hermon %p ICM CQC base = %llx\n", hermon, icm_offset ); 02353 icm_offset += icm_member_size; 02354 02355 /* Event queue contexts */ 02356 icm_member_size = icm_usage ( log_num_eqs, hermon->cap.eqc_entry_size ); 02357 icm_offset += icm_align ( icm_member_size, icm_offset ); 02358 MLX_FILL_1 ( init_hca, 32, 02359 qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_h, 02360 ( icm_offset >> 32 ) ); 02361 MLX_FILL_2 ( init_hca, 33, 02362 qpc_eec_cqc_eqc_rdb_parameters.eqc_base_addr_l, 02363 ( icm_offset >> 5 ), 02364 qpc_eec_cqc_eqc_rdb_parameters.log_num_of_eq, 02365 log_num_eqs ); 02366 DBGC ( hermon, "Hermon %p ICM EQC base = %llx\n", hermon, icm_offset ); 02367 icm_offset += icm_member_size; 02368 02369 /* Memory translation table */ 02370 icm_member_size = icm_usage ( log_num_mtts, 02371 hermon->cap.mtt_entry_size ); 02372 icm_offset += icm_align ( icm_member_size, icm_offset ); 02373 MLX_FILL_1 ( init_hca, 64, 02374 tpt_parameters.mtt_base_addr_h, ( icm_offset >> 32 ) ); 02375 MLX_FILL_1 ( init_hca, 65, 02376 tpt_parameters.mtt_base_addr_l, icm_offset ); 02377 DBGC ( hermon, "Hermon %p ICM MTT base = %llx\n", hermon, icm_offset ); 02378 icm_offset += icm_member_size; 02379 02380 /* Memory protection table */ 02381 log_num_mpts = fls ( hermon->cap.reserved_mrws + 1 - 1 ); 02382 icm_member_size = icm_usage ( log_num_mpts, 02383 hermon->cap.dmpt_entry_size ); 02384 icm_offset += icm_align ( icm_member_size, icm_offset ); 02385 MLX_FILL_1 ( init_hca, 60, 02386 tpt_parameters.dmpt_base_adr_h, ( icm_offset >> 32 ) ); 02387 MLX_FILL_1 ( init_hca, 61, 02388 tpt_parameters.dmpt_base_adr_l, icm_offset ); 02389 MLX_FILL_1 ( init_hca, 62, 02390 tpt_parameters.log_dmpt_sz, log_num_mpts ); 02391 DBGC ( hermon, "Hermon %p ICM DMPT base = %llx\n", hermon, icm_offset); 02392 icm_offset += icm_usage ( log_num_mpts, 02393 hermon->cap.dmpt_entry_size ); 02394 02395 /* Multicast table */ 02396 icm_member_size = ( ( 128 * sizeof ( struct hermonprm_mcg_entry ) + 02397 HERMON_PAGE_SIZE - 1 ) & ~( HERMON_PAGE_SIZE - 1 ) ); 02398 icm_offset += icm_align ( icm_member_size, icm_offset ); 02399 MLX_FILL_1 ( init_hca, 48, 02400 multicast_parameters.mc_base_addr_h, 02401 ( icm_offset >> 32 ) ); 02402 MLX_FILL_1 ( init_hca, 49, 02403 multicast_parameters.mc_base_addr_l, icm_offset ); 02404 MLX_FILL_1 ( init_hca, 52, 02405 multicast_parameters.log_mc_table_entry_sz, 02406 fls ( sizeof ( struct hermonprm_mcg_entry ) - 1 ) ); 02407 MLX_FILL_1 ( init_hca, 53, 02408 multicast_parameters.log_mc_table_hash_sz, 7 ); 02409 MLX_FILL_1 ( init_hca, 54, 02410 multicast_parameters.log_mc_table_sz, 7 ); 02411 DBGC ( hermon, "Hermon %p ICM MC base = %llx\n", hermon, icm_offset ); 02412 icm_offset += icm_member_size; 02413 02414 02415 hermon->icm_map[HERMON_ICM_OTHER].len = 02416 ( icm_offset - hermon->icm_map[HERMON_ICM_OTHER].offset ); 02417 02418 /* 02419 * Allocate and map physical memory for (portions of) ICM 02420 * 02421 * Map is: 02422 * ICM AUX area (aligned to its own size) 02423 * cMPT areas 02424 * Other areas 02425 */ 02426 02427 /* Calculate physical memory required for ICM */ 02428 icm_len = 0; 02429 for ( i = 0 ; i < HERMON_ICM_NUM_REGIONS ; i++ ) { 02430 icm_len += hermon->icm_map[i].len; 02431 } 02432 02433 /* Get ICM auxiliary area size */ 02434 memset ( &icm_size, 0, sizeof ( icm_size ) ); 02435 MLX_FILL_1 ( &icm_size, 0, value_hi, ( icm_offset >> 32 ) ); 02436 MLX_FILL_1 ( &icm_size, 1, value, icm_offset ); 02437 if ( ( rc = hermon_cmd_set_icm_size ( hermon, &icm_size, 02438 &icm_aux_size ) ) != 0 ) { 02439 DBGC ( hermon, "Hermon %p could not set ICM size: %s\n", 02440 hermon, strerror ( rc ) ); 02441 goto err_set_icm_size; 02442 } 02443 icm_aux_len = ( MLX_GET ( &icm_aux_size, value ) * HERMON_PAGE_SIZE ); 02444 02445 /* Allocate ICM data and auxiliary area */ 02446 DBGC ( hermon, "Hermon %p requires %zd kB ICM and %zd kB AUX ICM\n", 02447 hermon, ( icm_len / 1024 ), ( icm_aux_len / 1024 ) ); 02448 hermon->icm = umalloc ( icm_aux_len + icm_len ); 02449 if ( ! hermon->icm ) { 02450 rc = -ENOMEM; 02451 goto err_alloc; 02452 } 02453 icm_phys = user_to_phys ( hermon->icm, 0 ); 02454 02455 /* Map ICM auxiliary area */ 02456 DBGC ( hermon, "Hermon %p mapping ICM AUX => %08lx\n", 02457 hermon, icm_phys ); 02458 if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_icm_aux, 02459 0, icm_phys, icm_aux_len ) ) != 0 ) { 02460 DBGC ( hermon, "Hermon %p could not map AUX ICM: %s\n", 02461 hermon, strerror ( rc ) ); 02462 goto err_map_icm_aux; 02463 } 02464 icm_phys += icm_aux_len; 02465 02466 /* MAP ICM area */ 02467 for ( i = 0 ; i < HERMON_ICM_NUM_REGIONS ; i++ ) { 02468 DBGC ( hermon, "Hermon %p mapping ICM %llx+%zx => %08lx\n", 02469 hermon, hermon->icm_map[i].offset, 02470 hermon->icm_map[i].len, icm_phys ); 02471 if ( ( rc = hermon_map_vpm ( hermon, hermon_cmd_map_icm, 02472 hermon->icm_map[i].offset, 02473 icm_phys, 02474 hermon->icm_map[i].len ) ) != 0 ){ 02475 DBGC ( hermon, "Hermon %p could not map ICM: %s\n", 02476 hermon, strerror ( rc ) ); 02477 goto err_map_icm; 02478 } 02479 icm_phys += hermon->icm_map[i].len; 02480 } 02481 02482 return 0; 02483 02484 err_map_icm: 02485 assert ( i == 0 ); /* We don't handle partial failure at present */ 02486 err_map_icm_aux: 02487 hermon_cmd_unmap_icm_aux ( hermon ); 02488 ufree ( hermon->icm ); 02489 hermon->icm = UNULL; 02490 err_alloc: 02491 err_set_icm_size: 02492 return rc; 02493 }
| static void hermon_free_icm | ( | struct hermon * | hermon | ) | [static] |
Free ICM.
Definition at line 2500 of file hermon.c.
References fls, hermon_cmd_unmap_icm(), hermon_cmd_unmap_icm_aux(), HERMON_ICM_NUM_REGIONS, HERMON_PAGE_SIZE, hermon::icm, hermon::icm_map, hermon_icm_map::len, memset(), MLX_FILL_1, hermon_icm_map::offset, ufree(), and UNULL.
Referenced by hermon_probe(), and hermon_remove().
02500 { 02501 struct hermonprm_scalar_parameter unmap_icm; 02502 int i; 02503 02504 for ( i = ( HERMON_ICM_NUM_REGIONS - 1 ) ; i >= 0 ; i-- ) { 02505 memset ( &unmap_icm, 0, sizeof ( unmap_icm ) ); 02506 MLX_FILL_1 ( &unmap_icm, 0, value_hi, 02507 ( hermon->icm_map[i].offset >> 32 ) ); 02508 MLX_FILL_1 ( &unmap_icm, 1, value, 02509 hermon->icm_map[i].offset ); 02510 hermon_cmd_unmap_icm ( hermon, 02511 ( 1 << fls ( ( hermon->icm_map[i].len / 02512 HERMON_PAGE_SIZE ) - 1)), 02513 &unmap_icm ); 02514 } 02515 hermon_cmd_unmap_icm_aux ( hermon ); 02516 ufree ( hermon->icm ); 02517 hermon->icm = UNULL; 02518 }
| static int hermon_setup_mpt | ( | struct hermon * | hermon | ) | [static] |
Set up memory protection table.
| rc | Return status code |
Definition at line 2533 of file hermon.c.
References hermon::cap, DBGC, hermon_cmd_sw2hw_mpt(), HERMON_GLOBAL_PD, HERMON_MKEY_PREFIX, hermon::lkey, memset(), MLX_FILL_1, MLX_FILL_7, hermon_dev_cap::reserved_mrws, and strerror().
Referenced by hermon_probe().
02533 { 02534 struct hermonprm_mpt mpt; 02535 uint32_t key; 02536 int rc; 02537 02538 /* Derive key */ 02539 key = ( hermon->cap.reserved_mrws | HERMON_MKEY_PREFIX ); 02540 hermon->lkey = ( ( key << 8 ) | ( key >> 24 ) ); 02541 02542 /* Initialise memory protection table */ 02543 memset ( &mpt, 0, sizeof ( mpt ) ); 02544 MLX_FILL_7 ( &mpt, 0, 02545 atomic, 1, 02546 rw, 1, 02547 rr, 1, 02548 lw, 1, 02549 lr, 1, 02550 pa, 1, 02551 r_w, 1 ); 02552 MLX_FILL_1 ( &mpt, 2, mem_key, key ); 02553 MLX_FILL_1 ( &mpt, 3, 02554 pd, HERMON_GLOBAL_PD ); 02555 MLX_FILL_1 ( &mpt, 10, len64, 1 ); 02556 if ( ( rc = hermon_cmd_sw2hw_mpt ( hermon, 02557 hermon->cap.reserved_mrws, 02558 &mpt ) ) != 0 ) { 02559 DBGC ( hermon, "Hermon %p could not set up MPT: %s\n", 02560 hermon, strerror ( rc ) ); 02561 return rc; 02562 } 02563 02564 return 0; 02565 }
| static int hermon_configure_special_qps | ( | struct hermon * | hermon | ) | [static] |
Configure special queue pairs.
| rc | Return status code |
Definition at line 2573 of file hermon.c.
References hermon::cap, DBGC, hermon_cmd_conf_special_qp(), HERMON_NUM_SPECIAL_QPS, hermon::qpn_base, hermon_dev_cap::reserved_qps, hermon::special_qpn_base, and strerror().
Referenced by hermon_probe().
02573 { 02574 int rc; 02575 02576 /* Special QP block must be aligned on its own size */ 02577 hermon->special_qpn_base = ( ( hermon->cap.reserved_qps + 02578 HERMON_NUM_SPECIAL_QPS - 1 ) 02579 & ~( HERMON_NUM_SPECIAL_QPS - 1 ) ); 02580 hermon->qpn_base = ( hermon->special_qpn_base + 02581 HERMON_NUM_SPECIAL_QPS ); 02582 DBGC ( hermon, "Hermon %p special QPs at [%lx,%lx]\n", hermon, 02583 hermon->special_qpn_base, ( hermon->qpn_base - 1 ) ); 02584 02585 /* Issue command to configure special QPs */ 02586 if ( ( rc = hermon_cmd_conf_special_qp ( hermon, 0x00, 02587 hermon->special_qpn_base ) ) != 0 ) { 02588 DBGC ( hermon, "Hermon %p could not configure special QPs: " 02589 "%s\n", hermon, strerror ( rc ) ); 02590 return rc; 02591 } 02592 02593 return 0; 02594 }
| static void hermon_reset | ( | struct hermon * | hermon, | |
| struct pci_device * | pci | |||
| ) | [static] |
Reset device.
Definition at line 2602 of file hermon.c.
References hermon::config, HERMON_RESET_MAGIC, HERMON_RESET_OFFSET, HERMON_RESET_WAIT_TIME_MS, mdelay(), pci_backup(), PCI_CONFIG_BACKUP_EXCLUDE, pci_restore(), and writel.
Referenced by hermon_probe().
02603 { 02604 struct pci_config_backup backup; 02605 static const uint8_t backup_exclude[] = 02606 PCI_CONFIG_BACKUP_EXCLUDE ( 0x58, 0x5c ); 02607 02608 pci_backup ( pci, &backup, backup_exclude ); 02609 writel ( HERMON_RESET_MAGIC, 02610 ( hermon->config + HERMON_RESET_OFFSET ) ); 02611 mdelay ( HERMON_RESET_WAIT_TIME_MS ); 02612 pci_restore ( pci, &backup, backup_exclude ); 02613 }
| static int hermon_probe | ( | struct pci_device * | pci, | |
| const struct pci_device_id *id | __unused | |||
| ) | [static] |
Probe PCI device.
| pci | PCI device | |
| id | PCI ID |
| rc | Return status code |
Definition at line 2622 of file hermon.c.
References adjust_pci_device(), alloc_ibdev(), hermon::cap, hermon::config, DBGC, pci_device::dev, ib_device::dev, ENOMEM, free(), free_dma(), hermon_alloc_icm(), hermon_cmd_close_hca(), hermon_cmd_init_hca(), hermon_configure_special_qps(), hermon_create_eq(), hermon_destroy_eq(), hermon_free_icm(), hermon_get_cap(), hermon_mad(), HERMON_MBOX_ALIGN, HERMON_MBOX_SIZE, HERMON_PAGE_SIZE, HERMON_PCI_CONFIG_BAR, HERMON_PCI_CONFIG_BAR_SIZE, HERMON_PCI_UAR_BAR, HERMON_PORT_BASE, hermon_reset(), hermon_setup_mpt(), hermon_start_firmware(), hermon_stop_firmware(), HERMON_UAR_NON_EQ_PAGE, ib_set_drvdata(), ib_smc_update(), hermon::ibdev, ibdev_put(), ioremap(), hermon::lkey, hermon::mailbox_in, hermon::mailbox_out, malloc_dma(), memset(), MLX_FILL_1, hermon_dev_cap::num_ports, ib_device::op, pci_bar_start(), pci_set_drvdata(), ib_device::port, ib_device::rdma_key, register_ibdev(), strerror(), hermon::uar, unregister_ibdev(), version, and zalloc().
02623 { 02624 struct hermon *hermon; 02625 struct ib_device *ibdev; 02626 struct hermonprm_init_hca init_hca; 02627 unsigned int i; 02628 int rc; 02629 02630 /* Allocate Hermon device */ 02631 hermon = zalloc ( sizeof ( *hermon ) ); 02632 if ( ! hermon ) { 02633 rc = -ENOMEM; 02634 goto err_alloc_hermon; 02635 } 02636 pci_set_drvdata ( pci, hermon ); 02637 02638 /* Fix up PCI device */ 02639 adjust_pci_device ( pci ); 02640 02641 /* Get PCI BARs */ 02642 hermon->config = ioremap ( pci_bar_start ( pci, HERMON_PCI_CONFIG_BAR), 02643 HERMON_PCI_CONFIG_BAR_SIZE ); 02644 hermon->uar = ioremap ( pci_bar_start ( pci, HERMON_PCI_UAR_BAR ), 02645 HERMON_UAR_NON_EQ_PAGE * HERMON_PAGE_SIZE ); 02646 02647 /* Reset device */ 02648 hermon_reset ( hermon, pci ); 02649 02650 /* Allocate space for mailboxes */ 02651 hermon->mailbox_in = malloc_dma ( HERMON_MBOX_SIZE, 02652 HERMON_MBOX_ALIGN ); 02653 if ( ! hermon->mailbox_in ) { 02654 rc = -ENOMEM; 02655 goto err_mailbox_in; 02656 } 02657 hermon->mailbox_out = malloc_dma ( HERMON_MBOX_SIZE, 02658 HERMON_MBOX_ALIGN ); 02659 if ( ! hermon->mailbox_out ) { 02660 rc = -ENOMEM; 02661 goto err_mailbox_out; 02662 } 02663 02664 /* Start firmware */ 02665 if ( ( rc = hermon_start_firmware ( hermon ) ) != 0 ) 02666 goto err_start_firmware; 02667 02668 /* Get device limits */ 02669 if ( ( rc = hermon_get_cap ( hermon ) ) != 0 ) 02670 goto err_get_cap; 02671 02672 /* Allocate Infiniband devices */ 02673 for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) { 02674 ibdev = alloc_ibdev ( 0 ); 02675 if ( ! ibdev ) { 02676 rc = -ENOMEM; 02677 goto err_alloc_ibdev; 02678 } 02679 hermon->ibdev[i] = ibdev; 02680 ibdev->op = &hermon_ib_operations; 02681 ibdev->dev = &pci->dev; 02682 ibdev->port = ( HERMON_PORT_BASE + i ); 02683 ib_set_drvdata ( ibdev, hermon ); 02684 } 02685 02686 /* Allocate ICM */ 02687 memset ( &init_hca, 0, sizeof ( init_hca ) ); 02688 if ( ( rc = hermon_alloc_icm ( hermon, &init_hca ) ) != 0 ) 02689 goto err_alloc_icm; 02690 02691 /* Initialise HCA */ 02692 MLX_FILL_1 ( &init_hca, 0, version, 0x02 /* "Must be 0x02" */ ); 02693 MLX_FILL_1 ( &init_hca, 5, udp, 1 ); 02694 MLX_FILL_1 ( &init_hca, 74, uar_parameters.log_max_uars, 8 ); 02695 if ( ( rc = hermon_cmd_init_hca ( hermon, &init_hca ) ) != 0 ) { 02696 DBGC ( hermon, "Hermon %p could not initialise HCA: %s\n", 02697 hermon, strerror ( rc ) ); 02698 goto err_init_hca; 02699 } 02700 02701 /* Set up memory protection */ 02702 if ( ( rc = hermon_setup_mpt ( hermon ) ) != 0 ) 02703 goto err_setup_mpt; 02704 for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) 02705 hermon->ibdev[i]->rdma_key = hermon->lkey; 02706 02707 /* Set up event queue */ 02708 if ( ( rc = hermon_create_eq ( hermon ) ) != 0 ) 02709 goto err_create_eq; 02710 02711 /* Configure special QPs */ 02712 if ( ( rc = hermon_configure_special_qps ( hermon ) ) != 0 ) 02713 goto err_conf_special_qps; 02714 02715 /* Update IPoIB MAC address */ 02716 for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) { 02717 ib_smc_update ( hermon->ibdev[i], hermon_mad ); 02718 } 02719 02720 /* Register Infiniband devices */ 02721 for ( i = 0 ; i < hermon->cap.num_ports ; i++ ) { 02722 if ( ( rc = register_ibdev ( hermon->ibdev[i] ) ) != 0 ) { 02723 DBGC ( hermon, "Hermon %p could not register IB " 02724 "device: %s\n", hermon, strerror ( rc ) ); 02725 goto err_register_ibdev; 02726 } 02727 } 02728 02729 return 0; 02730 02731 i = hermon->cap.num_ports; 02732 err_register_ibdev: 02733 for ( i-- ; ( signed int ) i >= 0 ; i-- ) 02734 unregister_ibdev ( hermon->ibdev[i] ); 02735 err_conf_special_qps: 02736 hermon_destroy_eq ( hermon ); 02737 err_create_eq: 02738 err_setup_mpt: 02739 hermon_cmd_close_hca ( hermon ); 02740 err_init_hca: 02741 hermon_free_icm ( hermon ); 02742 err_alloc_icm: 02743 i = hermon->cap.num_ports; 02744 err_alloc_ibdev: 02745 for ( i-- ; ( signed int ) i >= 0 ; i-- ) 02746 ibdev_put ( hermon->ibdev[i] ); 02747 err_get_cap: 02748 hermon_stop_firmware ( hermon ); 02749 err_start_firmware: 02750 free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE ); 02751 err_mailbox_out: 02752 free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE ); 02753 err_mailbox_in: 02754 free ( hermon ); 02755 err_alloc_hermon: 02756 return rc; 02757 }
| static void hermon_remove | ( | struct pci_device * | pci | ) | [static] |
Remove PCI device.
| pci | PCI device |
Definition at line 2764 of file hermon.c.
References hermon::cap, free(), free_dma(), hermon_cmd_close_hca(), hermon_destroy_eq(), hermon_free_icm(), HERMON_MBOX_SIZE, hermon_stop_firmware(), hermon::ibdev, ibdev_put(), hermon::mailbox_in, hermon::mailbox_out, hermon_dev_cap::num_ports, pci_get_drvdata(), and unregister_ibdev().
02764 { 02765 struct hermon *hermon = pci_get_drvdata ( pci ); 02766 int i; 02767 02768 for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- ) 02769 unregister_ibdev ( hermon->ibdev[i] ); 02770 hermon_destroy_eq ( hermon ); 02771 hermon_cmd_close_hca ( hermon ); 02772 hermon_free_icm ( hermon ); 02773 hermon_stop_firmware ( hermon ); 02774 hermon_stop_firmware ( hermon ); 02775 free_dma ( hermon->mailbox_out, HERMON_MBOX_SIZE ); 02776 free_dma ( hermon->mailbox_in, HERMON_MBOX_SIZE ); 02777 for ( i = ( hermon->cap.num_ports - 1 ) ; i >= 0 ; i-- ) 02778 ibdev_put ( hermon->ibdev[i] ); 02779 free ( hermon ); 02780 }
uint8_t hermon_qp_st[] [static] |
Initial value:
{
[IB_QPT_SMI] = HERMON_ST_MLX,
[IB_QPT_GSI] = HERMON_ST_MLX,
[IB_QPT_UD] = HERMON_ST_UD,
[IB_QPT_RC] = HERMON_ST_RC,
}
Definition at line 914 of file hermon.c.
Referenced by hermon_create_qp().
unsigned int( * hermon_fill_send_wqe[])(struct ib_device *ibdev, struct ib_queue_pair *qp, struct ib_address_vector *av, struct io_buffer *iobuf, union hermon_send_wqe *wqe) [static] |
Initial value:
{
[IB_QPT_SMI] = hermon_fill_mlx_send_wqe,
[IB_QPT_GSI] = hermon_fill_mlx_send_wqe,
[IB_QPT_UD] = hermon_fill_ud_send_wqe,
[IB_QPT_RC] = hermon_fill_rc_send_wqe,
}
Referenced by hermon_post_send().
struct ib_device_operations hermon_ib_operations [static] |
Initial value:
{
.create_cq = hermon_create_cq,
.destroy_cq = hermon_destroy_cq,
.create_qp = hermon_create_qp,
.modify_qp = hermon_modify_qp,
.destroy_qp = hermon_destroy_qp,
.post_send = hermon_post_send,
.post_recv = hermon_post_recv,
.poll_cq = hermon_poll_cq,
.poll_eq = hermon_poll_eq,
.open = hermon_open,
.close = hermon_close,
.mcast_attach = hermon_mcast_attach,
.mcast_detach = hermon_mcast_detach,
.set_port_info = hermon_inform_sma,
.set_pkey_table = hermon_inform_sma,
}
struct pci_device_id hermon_nics[] [static] |
| struct pci_driver hermon_driver __pci_driver |
Initial value:
{
.ids = hermon_nics,
.id_count = ( sizeof ( hermon_nics ) / sizeof ( hermon_nics[0] ) ),
.probe = hermon_probe,
.remove = hermon_remove,
}
1.5.7.1