Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 59353
b: refs/heads/master
c: 8705ce5
h: refs/heads/master
i:
  59351: 889ce12
v: v3
  • Loading branch information
Joachim Fenkes authored and Roland Dreier committed Jul 10, 2007
1 parent ff2f43b commit c79a1d6
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 32 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b1cfe43d4b24144596d277133e0e5b715eea1347
refs/heads/master: 8705ce5b90118be93eb8b0ed6f49ca5ff377df24
6 changes: 6 additions & 0 deletions trunk/drivers/infiniband/hw/ehca/ehca_classes.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,17 @@ struct ehca_eq {
struct ehca_eqe_cache_entry eqe_cache[EHCA_EQE_CACHE_SIZE];
};

struct ehca_sma_attr {
u16 lid, lmc, sm_sl, sm_lid;
u16 pkey_tbl_len, pkeys[16];
};

struct ehca_sport {
struct ib_cq *ibcq_aqp1;
struct ib_qp *ibqp_aqp1;
enum ib_rate rate;
enum ib_port_state port_state;
struct ehca_sma_attr saved_attr;
};

struct ehca_shca {
Expand Down
34 changes: 34 additions & 0 deletions trunk/drivers/infiniband/hw/ehca/ehca_hca.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,40 @@ int ehca_query_port(struct ib_device *ibdev,
return ret;
}

int ehca_query_sma_attr(struct ehca_shca *shca,
u8 port, struct ehca_sma_attr *attr)
{
int ret = 0;
struct hipz_query_port *rblock;

rblock = ehca_alloc_fw_ctrlblock(GFP_ATOMIC);
if (!rblock) {
ehca_err(&shca->ib_device, "Can't allocate rblock memory.");
return -ENOMEM;
}

if (hipz_h_query_port(shca->ipz_hca_handle, port, rblock) != H_SUCCESS) {
ehca_err(&shca->ib_device, "Can't query port properties");
ret = -EINVAL;
goto query_sma_attr1;
}

memset(attr, 0, sizeof(struct ehca_sma_attr));

attr->lid = rblock->lid;
attr->lmc = rblock->lmc;
attr->sm_sl = rblock->sm_sl;
attr->sm_lid = rblock->sm_lid;

attr->pkey_tbl_len = rblock->pkey_tbl_len;
memcpy(attr->pkeys, rblock->pkey_entries, sizeof(attr->pkeys));

query_sma_attr1:
ehca_free_fw_ctrlblock(rblock);

return ret;
}

int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 *pkey)
{
int ret = 0;
Expand Down
89 changes: 58 additions & 31 deletions trunk/drivers/infiniband/hw/ehca/ehca_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#define NEQE_EVENT_CODE EHCA_BMASK_IBM(2,7)
#define NEQE_PORT_NUMBER EHCA_BMASK_IBM(8,15)
#define NEQE_PORT_AVAILABILITY EHCA_BMASK_IBM(16,16)
#define NEQE_DISRUPTIVE EHCA_BMASK_IBM(16,16)

#define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52,63)
#define ERROR_DATA_TYPE EHCA_BMASK_IBM(0,7)
Expand Down Expand Up @@ -286,55 +287,81 @@ static void parse_identifier(struct ehca_shca *shca, u64 eqe)
return;
}

static void parse_ec(struct ehca_shca *shca, u64 eqe)
static void dispatch_port_event(struct ehca_shca *shca, int port_num,
enum ib_event_type type, const char *msg)
{
struct ib_event event;

ehca_info(&shca->ib_device, "port %d %s.", port_num, msg);
event.device = &shca->ib_device;
event.event = type;
event.element.port_num = port_num;
ib_dispatch_event(&event);
}

static void notify_port_conf_change(struct ehca_shca *shca, int port_num)
{
struct ehca_sma_attr new_attr;
struct ehca_sma_attr *old_attr = &shca->sport[port_num - 1].saved_attr;

ehca_query_sma_attr(shca, port_num, &new_attr);

if (new_attr.sm_sl != old_attr->sm_sl ||
new_attr.sm_lid != old_attr->sm_lid)
dispatch_port_event(shca, port_num, IB_EVENT_SM_CHANGE,
"SM changed");

if (new_attr.lid != old_attr->lid ||
new_attr.lmc != old_attr->lmc)
dispatch_port_event(shca, port_num, IB_EVENT_LID_CHANGE,
"LID changed");

if (new_attr.pkey_tbl_len != old_attr->pkey_tbl_len ||
memcmp(new_attr.pkeys, old_attr->pkeys,
sizeof(u16) * new_attr.pkey_tbl_len))
dispatch_port_event(shca, port_num, IB_EVENT_PKEY_CHANGE,
"P_Key changed");

*old_attr = new_attr;
}

static void parse_ec(struct ehca_shca *shca, u64 eqe)
{
u8 ec = EHCA_BMASK_GET(NEQE_EVENT_CODE, eqe);
u8 port = EHCA_BMASK_GET(NEQE_PORT_NUMBER, eqe);

switch (ec) {
case 0x30: /* port availability change */
if (EHCA_BMASK_GET(NEQE_PORT_AVAILABILITY, eqe)) {
ehca_info(&shca->ib_device,
"port %x is active.", port);
event.device = &shca->ib_device;
event.event = IB_EVENT_PORT_ACTIVE;
event.element.port_num = port;
shca->sport[port - 1].port_state = IB_PORT_ACTIVE;
ib_dispatch_event(&event);
dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE,
"is active");
ehca_query_sma_attr(shca, port,
&shca->sport[port - 1].saved_attr);
} else {
ehca_info(&shca->ib_device,
"port %x is inactive.", port);
event.device = &shca->ib_device;
event.event = IB_EVENT_PORT_ERR;
event.element.port_num = port;
shca->sport[port - 1].port_state = IB_PORT_DOWN;
ib_dispatch_event(&event);
dispatch_port_event(shca, port, IB_EVENT_PORT_ERR,
"is inactive");
}
break;
case 0x31:
/* port configuration change
* disruptive change is caused by
* LID, PKEY or SM change
*/
ehca_warn(&shca->ib_device,
"disruptive port %x configuration change", port);

ehca_info(&shca->ib_device,
"port %x is inactive.", port);
event.device = &shca->ib_device;
event.event = IB_EVENT_PORT_ERR;
event.element.port_num = port;
shca->sport[port - 1].port_state = IB_PORT_DOWN;
ib_dispatch_event(&event);

ehca_info(&shca->ib_device,
"port %x is active.", port);
event.device = &shca->ib_device;
event.event = IB_EVENT_PORT_ACTIVE;
event.element.port_num = port;
shca->sport[port - 1].port_state = IB_PORT_ACTIVE;
ib_dispatch_event(&event);
if (EHCA_BMASK_GET(NEQE_DISRUPTIVE, eqe)) {
ehca_warn(&shca->ib_device, "disruptive port "
"%d configuration change", port);

shca->sport[port - 1].port_state = IB_PORT_DOWN;
dispatch_port_event(shca, port, IB_EVENT_PORT_ERR,
"is inactive");

shca->sport[port - 1].port_state = IB_PORT_ACTIVE;
dispatch_port_event(shca, port, IB_EVENT_PORT_ACTIVE,
"is active");
} else
notify_port_conf_change(shca, port);
break;
case 0x32: /* adapter malfunction */
ehca_err(&shca->ib_device, "Adapter malfunction.");
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/infiniband/hw/ehca/ehca_iverbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props);
int ehca_query_port(struct ib_device *ibdev, u8 port,
struct ib_port_attr *props);

int ehca_query_sma_attr(struct ehca_shca *shca, u8 port,
struct ehca_sma_attr *attr);

int ehca_query_pkey(struct ib_device *ibdev, u8 port, u16 index, u16 * pkey);

int ehca_query_gid(struct ib_device *ibdev, u8 port, int index,
Expand Down

0 comments on commit c79a1d6

Please sign in to comment.