diff options
author | Divy Le Ray <divy@chelsio.com> | 2007-12-17 21:47:31 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:07:22 -0500 |
commit | b881955b7d045e7486e9af08398242aeb7199f67 (patch) | |
tree | fadf96f161a8a03bd285c4b63140407ab5f527d9 /drivers/net/cxgb3/cxgb3_main.c | |
parent | 06daa168b681797c91ce1fd567d706b9b84738e2 (diff) |
cxgb3 - parity initialization for T3C adapters.
Add parity initialization for T3C adapters.
Signed-off-by: Divy Le Ray <divy@chelsio.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/cxgb3/cxgb3_main.c')
-rw-r--r-- | drivers/net/cxgb3/cxgb3_main.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c index 944423c497d2..d1aa7779796e 100644 --- a/drivers/net/cxgb3/cxgb3_main.c +++ b/drivers/net/cxgb3/cxgb3_main.c | |||
@@ -306,6 +306,77 @@ static int request_msix_data_irqs(struct adapter *adap) | |||
306 | return 0; | 306 | return 0; |
307 | } | 307 | } |
308 | 308 | ||
309 | static int await_mgmt_replies(struct adapter *adap, unsigned long init_cnt, | ||
310 | unsigned long n) | ||
311 | { | ||
312 | int attempts = 5; | ||
313 | |||
314 | while (adap->sge.qs[0].rspq.offload_pkts < init_cnt + n) { | ||
315 | if (!--attempts) | ||
316 | return -ETIMEDOUT; | ||
317 | msleep(10); | ||
318 | } | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int init_tp_parity(struct adapter *adap) | ||
323 | { | ||
324 | int i; | ||
325 | struct sk_buff *skb; | ||
326 | struct cpl_set_tcb_field *greq; | ||
327 | unsigned long cnt = adap->sge.qs[0].rspq.offload_pkts; | ||
328 | |||
329 | t3_tp_set_offload_mode(adap, 1); | ||
330 | |||
331 | for (i = 0; i < 16; i++) { | ||
332 | struct cpl_smt_write_req *req; | ||
333 | |||
334 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | ||
335 | req = (struct cpl_smt_write_req *)__skb_put(skb, sizeof(*req)); | ||
336 | memset(req, 0, sizeof(*req)); | ||
337 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | ||
338 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_SMT_WRITE_REQ, i)); | ||
339 | req->iff = i; | ||
340 | t3_mgmt_tx(adap, skb); | ||
341 | } | ||
342 | |||
343 | for (i = 0; i < 2048; i++) { | ||
344 | struct cpl_l2t_write_req *req; | ||
345 | |||
346 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | ||
347 | req = (struct cpl_l2t_write_req *)__skb_put(skb, sizeof(*req)); | ||
348 | memset(req, 0, sizeof(*req)); | ||
349 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | ||
350 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_L2T_WRITE_REQ, i)); | ||
351 | req->params = htonl(V_L2T_W_IDX(i)); | ||
352 | t3_mgmt_tx(adap, skb); | ||
353 | } | ||
354 | |||
355 | for (i = 0; i < 2048; i++) { | ||
356 | struct cpl_rte_write_req *req; | ||
357 | |||
358 | skb = alloc_skb(sizeof(*req), GFP_KERNEL | __GFP_NOFAIL); | ||
359 | req = (struct cpl_rte_write_req *)__skb_put(skb, sizeof(*req)); | ||
360 | memset(req, 0, sizeof(*req)); | ||
361 | req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | ||
362 | OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RTE_WRITE_REQ, i)); | ||
363 | req->l2t_idx = htonl(V_L2T_W_IDX(i)); | ||
364 | t3_mgmt_tx(adap, skb); | ||
365 | } | ||
366 | |||
367 | skb = alloc_skb(sizeof(*greq), GFP_KERNEL | __GFP_NOFAIL); | ||
368 | greq = (struct cpl_set_tcb_field *)__skb_put(skb, sizeof(*greq)); | ||
369 | memset(greq, 0, sizeof(*greq)); | ||
370 | greq->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); | ||
371 | OPCODE_TID(greq) = htonl(MK_OPCODE_TID(CPL_SET_TCB_FIELD, 0)); | ||
372 | greq->mask = cpu_to_be64(1); | ||
373 | t3_mgmt_tx(adap, skb); | ||
374 | |||
375 | i = await_mgmt_replies(adap, cnt, 16 + 2048 + 2048 + 1); | ||
376 | t3_tp_set_offload_mode(adap, 0); | ||
377 | return i; | ||
378 | } | ||
379 | |||
309 | /** | 380 | /** |
310 | * setup_rss - configure RSS | 381 | * setup_rss - configure RSS |
311 | * @adap: the adapter | 382 | * @adap: the adapter |
@@ -817,6 +888,7 @@ static int cxgb_up(struct adapter *adap) | |||
817 | if (err) | 888 | if (err) |
818 | goto out; | 889 | goto out; |
819 | 890 | ||
891 | t3_set_reg_field(adap, A_TP_PARA_REG5, 0, F_RXDDPOFFINIT); | ||
820 | t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12)); | 892 | t3_write_reg(adap, A_ULPRX_TDDP_PSZ, V_HPZ0(PAGE_SHIFT - 12)); |
821 | 893 | ||
822 | err = setup_sge_qsets(adap); | 894 | err = setup_sge_qsets(adap); |
@@ -856,6 +928,16 @@ static int cxgb_up(struct adapter *adap) | |||
856 | t3_sge_start(adap); | 928 | t3_sge_start(adap); |
857 | t3_intr_enable(adap); | 929 | t3_intr_enable(adap); |
858 | 930 | ||
931 | if (adap->params.rev >= T3_REV_C && !(adap->flags & TP_PARITY_INIT) && | ||
932 | is_offload(adap) && init_tp_parity(adap) == 0) | ||
933 | adap->flags |= TP_PARITY_INIT; | ||
934 | |||
935 | if (adap->flags & TP_PARITY_INIT) { | ||
936 | t3_write_reg(adap, A_TP_INT_CAUSE, | ||
937 | F_CMCACHEPERR | F_ARPLUTPERR); | ||
938 | t3_write_reg(adap, A_TP_INT_ENABLE, 0x7fbfffff); | ||
939 | } | ||
940 | |||
859 | if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX) | 941 | if ((adap->flags & (USING_MSIX | QUEUES_BOUND)) == USING_MSIX) |
860 | bind_qsets(adap); | 942 | bind_qsets(adap); |
861 | adap->flags |= QUEUES_BOUND; | 943 | adap->flags |= QUEUES_BOUND; |