be2net: use EQ_CREATEv2 for SH-R
EQ_CREATEv2 explicitly returns the msix-index associated with a EQ. For SH-R this is needed if EQs need to be deleted and re-created without resetting a function. Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
b1dcdc68b1
commit
f2f781a759
@@ -189,6 +189,7 @@ struct be_eq_obj {
|
|||||||
u32 cur_eqd; /* in usecs */
|
u32 cur_eqd; /* in usecs */
|
||||||
|
|
||||||
u8 idx; /* array index */
|
u8 idx; /* array index */
|
||||||
|
u8 msix_idx;
|
||||||
u16 tx_budget;
|
u16 tx_budget;
|
||||||
u16 spurious_intr;
|
u16 spurious_intr;
|
||||||
struct napi_struct napi;
|
struct napi_struct napi;
|
||||||
|
@@ -678,31 +678,6 @@ static void be_cmd_page_addrs_prepare(struct phys_addr *pages, u32 max_pages,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Converts interrupt delay in microseconds to multiplier value */
|
|
||||||
static u32 eq_delay_to_mult(u32 usec_delay)
|
|
||||||
{
|
|
||||||
#define MAX_INTR_RATE 651042
|
|
||||||
const u32 round = 10;
|
|
||||||
u32 multiplier;
|
|
||||||
|
|
||||||
if (usec_delay == 0)
|
|
||||||
multiplier = 0;
|
|
||||||
else {
|
|
||||||
u32 interrupt_rate = 1000000 / usec_delay;
|
|
||||||
/* Max delay, corresponding to the lowest interrupt rate */
|
|
||||||
if (interrupt_rate == 0)
|
|
||||||
multiplier = 1023;
|
|
||||||
else {
|
|
||||||
multiplier = (MAX_INTR_RATE - interrupt_rate) * round;
|
|
||||||
multiplier /= interrupt_rate;
|
|
||||||
/* Round the multiplier to the closest value.*/
|
|
||||||
multiplier = (multiplier + round/2) / round;
|
|
||||||
multiplier = min(multiplier, (u32)1023);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return multiplier;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
|
static inline struct be_mcc_wrb *wrb_from_mbox(struct be_adapter *adapter)
|
||||||
{
|
{
|
||||||
struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
|
struct be_dma_mem *mbox_mem = &adapter->mbox_mem;
|
||||||
@@ -790,13 +765,12 @@ int be_cmd_fw_clean(struct be_adapter *adapter)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int be_cmd_eq_create(struct be_adapter *adapter,
|
int be_cmd_eq_create(struct be_adapter *adapter, struct be_eq_obj *eqo)
|
||||||
struct be_queue_info *eq, int eq_delay)
|
|
||||||
{
|
{
|
||||||
struct be_mcc_wrb *wrb;
|
struct be_mcc_wrb *wrb;
|
||||||
struct be_cmd_req_eq_create *req;
|
struct be_cmd_req_eq_create *req;
|
||||||
struct be_dma_mem *q_mem = &eq->dma_mem;
|
struct be_dma_mem *q_mem = &eqo->q.dma_mem;
|
||||||
int status;
|
int status, ver = 0;
|
||||||
|
|
||||||
if (mutex_lock_interruptible(&adapter->mbox_lock))
|
if (mutex_lock_interruptible(&adapter->mbox_lock))
|
||||||
return -1;
|
return -1;
|
||||||
@@ -807,15 +781,18 @@ int be_cmd_eq_create(struct be_adapter *adapter,
|
|||||||
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
be_wrb_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
|
||||||
OPCODE_COMMON_EQ_CREATE, sizeof(*req), wrb, NULL);
|
OPCODE_COMMON_EQ_CREATE, sizeof(*req), wrb, NULL);
|
||||||
|
|
||||||
|
/* Support for EQ_CREATEv2 available only SH-R onwards */
|
||||||
|
if (!(BEx_chip(adapter) || lancer_chip(adapter)))
|
||||||
|
ver = 2;
|
||||||
|
|
||||||
|
req->hdr.version = ver;
|
||||||
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
|
req->num_pages = cpu_to_le16(PAGES_4K_SPANNED(q_mem->va, q_mem->size));
|
||||||
|
|
||||||
AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
|
AMAP_SET_BITS(struct amap_eq_context, valid, req->context, 1);
|
||||||
/* 4byte eqe*/
|
/* 4byte eqe*/
|
||||||
AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
|
AMAP_SET_BITS(struct amap_eq_context, size, req->context, 0);
|
||||||
AMAP_SET_BITS(struct amap_eq_context, count, req->context,
|
AMAP_SET_BITS(struct amap_eq_context, count, req->context,
|
||||||
__ilog2_u32(eq->len/256));
|
__ilog2_u32(eqo->q.len / 256));
|
||||||
AMAP_SET_BITS(struct amap_eq_context, delaymult, req->context,
|
|
||||||
eq_delay_to_mult(eq_delay));
|
|
||||||
be_dws_cpu_to_le(req->context, sizeof(req->context));
|
be_dws_cpu_to_le(req->context, sizeof(req->context));
|
||||||
|
|
||||||
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
|
be_cmd_page_addrs_prepare(req->pages, ARRAY_SIZE(req->pages), q_mem);
|
||||||
@@ -823,8 +800,10 @@ int be_cmd_eq_create(struct be_adapter *adapter,
|
|||||||
status = be_mbox_notify_wait(adapter);
|
status = be_mbox_notify_wait(adapter);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
|
struct be_cmd_resp_eq_create *resp = embedded_payload(wrb);
|
||||||
eq->id = le16_to_cpu(resp->eq_id);
|
eqo->q.id = le16_to_cpu(resp->eq_id);
|
||||||
eq->created = true;
|
eqo->msix_idx =
|
||||||
|
(ver == 2) ? le16_to_cpu(resp->msix_idx) : eqo->idx;
|
||||||
|
eqo->q.created = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&adapter->mbox_lock);
|
mutex_unlock(&adapter->mbox_lock);
|
||||||
|
@@ -307,7 +307,7 @@ struct be_cmd_req_eq_create {
|
|||||||
struct be_cmd_resp_eq_create {
|
struct be_cmd_resp_eq_create {
|
||||||
struct be_cmd_resp_hdr resp_hdr;
|
struct be_cmd_resp_hdr resp_hdr;
|
||||||
u16 eq_id; /* sword */
|
u16 eq_id; /* sword */
|
||||||
u16 rsvd0; /* sword */
|
u16 msix_idx; /* available only in v2 */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
/******************** Mac query ***************************/
|
/******************** Mac query ***************************/
|
||||||
@@ -1851,8 +1851,7 @@ extern int be_cmd_if_create(struct be_adapter *adapter, u32 cap_flags,
|
|||||||
u32 en_flags, u32 *if_handle, u32 domain);
|
u32 en_flags, u32 *if_handle, u32 domain);
|
||||||
extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle,
|
extern int be_cmd_if_destroy(struct be_adapter *adapter, int if_handle,
|
||||||
u32 domain);
|
u32 domain);
|
||||||
extern int be_cmd_eq_create(struct be_adapter *adapter,
|
extern int be_cmd_eq_create(struct be_adapter *adapter, struct be_eq_obj *eqo);
|
||||||
struct be_queue_info *eq, int eq_delay);
|
|
||||||
extern int be_cmd_cq_create(struct be_adapter *adapter,
|
extern int be_cmd_cq_create(struct be_adapter *adapter,
|
||||||
struct be_queue_info *cq, struct be_queue_info *eq,
|
struct be_queue_info *cq, struct be_queue_info *eq,
|
||||||
bool no_delay, int num_cqe_dma_coalesce);
|
bool no_delay, int num_cqe_dma_coalesce);
|
||||||
|
@@ -1939,7 +1939,7 @@ static int be_evt_queues_create(struct be_adapter *adapter)
|
|||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
rc = be_cmd_eq_create(adapter, eq, eqo->cur_eqd);
|
rc = be_cmd_eq_create(adapter, eqo);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -2443,7 +2443,7 @@ done:
|
|||||||
static inline int be_msix_vec_get(struct be_adapter *adapter,
|
static inline int be_msix_vec_get(struct be_adapter *adapter,
|
||||||
struct be_eq_obj *eqo)
|
struct be_eq_obj *eqo)
|
||||||
{
|
{
|
||||||
return adapter->msix_entries[eqo->idx].vector;
|
return adapter->msix_entries[eqo->msix_idx].vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int be_msix_register(struct be_adapter *adapter)
|
static int be_msix_register(struct be_adapter *adapter)
|
||||||
|
Reference in New Issue
Block a user