Skip to content

Commit

Permalink
cxgb3 - parity initialization for T3C adapters.
Browse files Browse the repository at this point in the history
Add parity initialization for T3C adapters.

Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
  • Loading branch information
Divy Le Ray authored and David S. Miller committed Jan 28, 2008
1 parent 06daa16 commit b881955
Show file tree
Hide file tree
Showing 6 changed files with 472 additions and 29 deletions.
1 change: 1 addition & 0 deletions drivers/net/cxgb3/adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ enum { /* adapter flags */
USING_MSI = (1 << 1),
USING_MSIX = (1 << 2),
QUEUES_BOUND = (1 << 3),
TP_PARITY_INIT = (1 << 4),
};

struct fl_pg_chunk {
Expand Down
82 changes: 82 additions & 0 deletions drivers/net/cxgb3/cxgb3_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,77 @@ static int request_msix_data_irqs(struct adapter *adap)
return 0;
}

static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt,
unsigned long n)
{
int attempts = 5;

while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) {
if (!--attempts)
return -ETIMEDOUT;
msleep(10);
}
return 0;
}

static int init_tp_parity(struct adapter *adap)
{
int i;
struct sk_buff *skb;
struct cpl_set_tcb_field *greq;
unsigned long cnt = adap->sge.qs[0].rspq.offload_pkts;

t3_tp_set_offload_mode(adap, 1);

for (i = 0; i < 16; i++) {
struct cpl_smt_write_req *req;

skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i));
req->iff = i;
t3_mgmt_tx(adap, skb);
}

for (i = 0; i < 2048; i++) {
struct cpl_l2t_write_req *req;

skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i));
req->params = htonl(V_L2T_W_IDX(i));
t3_mgmt_tx(adap, skb);
}

for (i = 0; i < 2048; i++) {
struct cpl_rte_write_req *req;

skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL);
req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req));
memset(req, 0, sizeof(*req));
req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i));
req->l2t_idx = htonl(V_L2T_W_IDX(i));
t3_mgmt_tx(adap, skb);
}

skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL);
greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq));
memset(greq, 0, sizeof(*greq));
greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD));
OPCODE_TID(greq) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, 0));
greq->mask = cpu_to_be64(1);
t3_mgmt_tx(adap, skb);

i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1);
t3_tp_set_offload_mode(adap, 0);
return i;
}

/**
* setup_rss - configure RSS
* @adap: the adapter
Expand Down Expand Up @@ -817,6 +888,7 @@ static int cxgb_up(struct adapter *adap)
if (err)
goto out;

t3_set_reg_field(adap, A_TP_PARA_REG5, 0, F_RXDDPOFFINIT);
t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12));

err = setup_sge_qsets(adap);
Expand Down Expand Up @@ -856,6 +928,16 @@ static int cxgb_up(struct adapter *adap)
t3_sge_start(adap);
t3_intr_enable(adap);

if (adap->params.rev >= T3_REV_C && !(adap->flags & TP_PARITY_INIT) &&
is_offload(adap) && init_tp_parity(adap) == 0)
adap->flags |= TP_PARITY_INIT;

if (adap->flags & TP_PARITY_INIT) {
t3_write_reg(adap, A_TP_INT_CAUSE,
F_CMCACHEPERR | F_ARPLUTPERR);
t3_write_reg(adap, A_TP_INT_ENABLE, 0x7fbfffff);
}

if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX)
bind_qsets(adap);
adap->flags |= QUEUES_BOUND;
Expand Down
15 changes: 13 additions & 2 deletions drivers/net/cxgb3/cxgb3_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,8 +403,6 @@ static int cxgb_offload_ctl(struct t3cdev *tdev, unsigned int req, void *data)
static int rx_offload_blackhole(struct t3cdev *dev, struct sk_buff **skbs,
int n)
{
CH_ERR(tdev2adap(dev), "%d unexpected offload packets, first data %u\n",
n, ntohl(*(__be32 *)skbs[0]->data));
while (n--)
dev_kfree_skb_any(skbs[n]);
return 0;
Expand Down Expand Up @@ -634,6 +632,18 @@ static int do_l2t_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
return CPL_RET_BUF_DONE;
}

static int do_rte_write_rpl(struct t3cdev *dev, struct sk_buff *skb)
{
struct cpl_rte_write_rpl *rpl = cplhdr(skb);

if (rpl->status != CPL_ERR_NONE)
printk(KERN_ERR
"Unexpected RTE_WRITE_RPL status %u for entry %u\n",
rpl->status, GET_TID(rpl));

return CPL_RET_BUF_DONE;
}

static int do_act_open_rpl(struct t3cdev *dev, struct sk_buff *skb)
{
struct cpl_act_open_rpl *rpl = cplhdr(skb);
Expand Down Expand Up @@ -1257,6 +1267,7 @@ void __init cxgb3_offload_init(void)

t3_register_cpl_handler(CPL_SMT_WRITE_RPL, do_smt_write_rpl);
t3_register_cpl_handler(CPL_L2T_WRITE_RPL, do_l2t_write_rpl);
t3_register_cpl_handler(CPL_RTE_WRITE_RPL, do_rte_write_rpl);
t3_register_cpl_handler(CPL_PASS_OPEN_RPL, do_stid_rpl);
t3_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_stid_rpl);
t3_register_cpl_handler(CPL_PASS_ACCEPT_REQ, do_cr);
Expand Down
Loading

0 comments on commit b881955

Please sign in to comment.