.. | .. |
---|
35 | 35 | |
---|
36 | 36 | #include "../libcxgbi.h" |
---|
37 | 37 | |
---|
| 38 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 39 | +#include <net/dcbevent.h> |
---|
| 40 | +#include "cxgb4_dcb.h" |
---|
| 41 | +#endif |
---|
| 42 | + |
---|
38 | 43 | #define DRV_MODULE_NAME "cxgb4i" |
---|
39 | 44 | #define DRV_MODULE_DESC "Chelsio T4-T6 iSCSI Driver" |
---|
40 | 45 | #define DRV_MODULE_VERSION "0.9.5-ko" |
---|
.. | .. |
---|
55 | 60 | #define CXGB4I_DEFAULT_10G_RCV_WIN (256 * 1024) |
---|
56 | 61 | static int cxgb4i_rcv_win = -1; |
---|
57 | 62 | module_param(cxgb4i_rcv_win, int, 0644); |
---|
58 | | -MODULE_PARM_DESC(cxgb4i_rcv_win, "TCP reveive window in bytes"); |
---|
| 63 | +MODULE_PARM_DESC(cxgb4i_rcv_win, "TCP receive window in bytes"); |
---|
59 | 64 | |
---|
60 | 65 | #define CXGB4I_DEFAULT_10G_SND_WIN (128 * 1024) |
---|
61 | 66 | static int cxgb4i_snd_win = -1; |
---|
.. | .. |
---|
108 | 113 | .eh_device_reset_handler = iscsi_eh_device_reset, |
---|
109 | 114 | .eh_target_reset_handler = iscsi_eh_recover_target, |
---|
110 | 115 | .target_alloc = iscsi_target_alloc, |
---|
111 | | - .use_clustering = DISABLE_CLUSTERING, |
---|
| 116 | + .dma_boundary = PAGE_SIZE - 1, |
---|
112 | 117 | .this_id = -1, |
---|
113 | 118 | .track_queue_depth = 1, |
---|
114 | 119 | }; |
---|
.. | .. |
---|
129 | 134 | /* connection management */ |
---|
130 | 135 | .create_conn = cxgbi_create_conn, |
---|
131 | 136 | .bind_conn = cxgbi_bind_conn, |
---|
| 137 | + .unbind_conn = iscsi_conn_unbind, |
---|
132 | 138 | .destroy_conn = iscsi_tcp_conn_teardown, |
---|
133 | 139 | .start_conn = iscsi_conn_start, |
---|
134 | 140 | .stop_conn = iscsi_conn_stop, |
---|
.. | .. |
---|
154 | 160 | /* Error recovery timeout call */ |
---|
155 | 161 | .session_recovery_timedout = iscsi_session_recovery_timedout, |
---|
156 | 162 | }; |
---|
| 163 | + |
---|
| 164 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 165 | +static int |
---|
| 166 | +cxgb4_dcb_change_notify(struct notifier_block *, unsigned long, void *); |
---|
| 167 | + |
---|
| 168 | +static struct notifier_block cxgb4_dcb_change = { |
---|
| 169 | + .notifier_call = cxgb4_dcb_change_notify, |
---|
| 170 | +}; |
---|
| 171 | +#endif |
---|
157 | 172 | |
---|
158 | 173 | static struct scsi_transport_template *cxgb4i_stt; |
---|
159 | 174 | |
---|
.. | .. |
---|
183 | 198 | if (likely(cxgbi_skcb_test_flag(skb, SKCBF_TX_NEED_HDR))) |
---|
184 | 199 | len += sizeof(struct fw_ofld_tx_data_wr); |
---|
185 | 200 | |
---|
186 | | - return len <= MAX_IMM_TX_PKT_LEN; |
---|
| 201 | + if (likely(cxgbi_skcb_test_flag((struct sk_buff *)skb, SKCBF_TX_ISO))) |
---|
| 202 | + len += sizeof(struct cpl_tx_data_iso); |
---|
| 203 | + |
---|
| 204 | + return (len <= MAX_IMM_OFLD_TX_DATA_WR_LEN); |
---|
187 | 205 | } |
---|
188 | 206 | |
---|
189 | 207 | static void send_act_open_req(struct cxgbi_sock *csk, struct sk_buff *skb, |
---|
.. | .. |
---|
574 | 592 | int nparams, flowclen16, flowclen; |
---|
575 | 593 | |
---|
576 | 594 | nparams = FLOWC_WR_NPARAMS_MIN; |
---|
| 595 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 596 | + nparams++; |
---|
| 597 | +#endif |
---|
577 | 598 | flowclen = offsetof(struct fw_flowc_wr, mnemval[nparams]); |
---|
578 | 599 | flowclen16 = DIV_ROUND_UP(flowclen, 16); |
---|
579 | 600 | flowclen = flowclen16 * 16; |
---|
.. | .. |
---|
595 | 616 | struct fw_flowc_wr *flowc; |
---|
596 | 617 | int nparams, flowclen16, flowclen; |
---|
597 | 618 | |
---|
| 619 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 620 | + u16 vlan = ((struct l2t_entry *)csk->l2t)->vlan; |
---|
| 621 | +#endif |
---|
598 | 622 | flowclen16 = tx_flowc_wr_credits(&nparams, &flowclen); |
---|
599 | 623 | skb = alloc_wr(flowclen, 0, GFP_ATOMIC); |
---|
600 | 624 | flowc = (struct fw_flowc_wr *)skb->head; |
---|
.. | .. |
---|
621 | 645 | flowc->mnemval[8].mnemonic = 0; |
---|
622 | 646 | flowc->mnemval[8].val = 0; |
---|
623 | 647 | flowc->mnemval[8].mnemonic = FW_FLOWC_MNEM_TXDATAPLEN_MAX; |
---|
624 | | - flowc->mnemval[8].val = 16384; |
---|
| 648 | + if (csk->cdev->skb_iso_txhdr) |
---|
| 649 | + flowc->mnemval[8].val = cpu_to_be32(CXGBI_MAX_ISO_DATA_IN_SKB); |
---|
| 650 | + else |
---|
| 651 | + flowc->mnemval[8].val = cpu_to_be32(16128); |
---|
| 652 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 653 | + flowc->mnemval[9].mnemonic = FW_FLOWC_MNEM_DCBPRIO; |
---|
| 654 | + if (vlan == CPL_L2T_VLAN_NONE) { |
---|
| 655 | + pr_warn_ratelimited("csk %u without VLAN Tag on DCB Link\n", |
---|
| 656 | + csk->tid); |
---|
| 657 | + flowc->mnemval[9].val = cpu_to_be32(0); |
---|
| 658 | + } else { |
---|
| 659 | + flowc->mnemval[9].val = cpu_to_be32((vlan & VLAN_PRIO_MASK) >> |
---|
| 660 | + VLAN_PRIO_SHIFT); |
---|
| 661 | + } |
---|
| 662 | +#endif |
---|
625 | 663 | |
---|
626 | 664 | set_wr_txq(skb, CPL_PRIORITY_DATA, csk->port_id); |
---|
627 | 665 | |
---|
.. | .. |
---|
636 | 674 | return flowclen16; |
---|
637 | 675 | } |
---|
638 | 676 | |
---|
639 | | -static inline void make_tx_data_wr(struct cxgbi_sock *csk, struct sk_buff *skb, |
---|
640 | | - int dlen, int len, u32 credits, int compl) |
---|
| 677 | +static void |
---|
| 678 | +cxgb4i_make_tx_iso_cpl(struct sk_buff *skb, struct cpl_tx_data_iso *cpl) |
---|
641 | 679 | { |
---|
| 680 | + struct cxgbi_iso_info *info = (struct cxgbi_iso_info *)skb->head; |
---|
| 681 | + u32 imm_en = !!(info->flags & CXGBI_ISO_INFO_IMM_ENABLE); |
---|
| 682 | + u32 fslice = !!(info->flags & CXGBI_ISO_INFO_FSLICE); |
---|
| 683 | + u32 lslice = !!(info->flags & CXGBI_ISO_INFO_LSLICE); |
---|
| 684 | + u32 pdu_type = (info->op == ISCSI_OP_SCSI_CMD) ? 0 : 1; |
---|
| 685 | + u32 submode = cxgbi_skcb_tx_ulp_mode(skb) & 0x3; |
---|
| 686 | + |
---|
| 687 | + cpl->op_to_scsi = cpu_to_be32(CPL_TX_DATA_ISO_OP_V(CPL_TX_DATA_ISO) | |
---|
| 688 | + CPL_TX_DATA_ISO_FIRST_V(fslice) | |
---|
| 689 | + CPL_TX_DATA_ISO_LAST_V(lslice) | |
---|
| 690 | + CPL_TX_DATA_ISO_CPLHDRLEN_V(0) | |
---|
| 691 | + CPL_TX_DATA_ISO_HDRCRC_V(submode & 1) | |
---|
| 692 | + CPL_TX_DATA_ISO_PLDCRC_V(((submode >> 1) & 1)) | |
---|
| 693 | + CPL_TX_DATA_ISO_IMMEDIATE_V(imm_en) | |
---|
| 694 | + CPL_TX_DATA_ISO_SCSI_V(pdu_type)); |
---|
| 695 | + |
---|
| 696 | + cpl->ahs_len = info->ahs; |
---|
| 697 | + cpl->mpdu = cpu_to_be16(DIV_ROUND_UP(info->mpdu, 4)); |
---|
| 698 | + cpl->burst_size = cpu_to_be32(info->burst_size); |
---|
| 699 | + cpl->len = cpu_to_be32(info->len); |
---|
| 700 | + cpl->reserved2_seglen_offset = |
---|
| 701 | + cpu_to_be32(CPL_TX_DATA_ISO_SEGLEN_OFFSET_V(info->segment_offset)); |
---|
| 702 | + cpl->datasn_offset = cpu_to_be32(info->datasn_offset); |
---|
| 703 | + cpl->buffer_offset = cpu_to_be32(info->buffer_offset); |
---|
| 704 | + cpl->reserved3 = cpu_to_be32(0); |
---|
| 705 | + log_debug(1 << CXGBI_DBG_ISCSI | 1 << CXGBI_DBG_PDU_TX, |
---|
| 706 | + "iso: flags 0x%x, op %u, ahs %u, num_pdu %u, mpdu %u, " |
---|
| 707 | + "burst_size %u, iso_len %u\n", |
---|
| 708 | + info->flags, info->op, info->ahs, info->num_pdu, |
---|
| 709 | + info->mpdu, info->burst_size << 2, info->len); |
---|
| 710 | +} |
---|
| 711 | + |
---|
| 712 | +static void |
---|
| 713 | +cxgb4i_make_tx_data_wr(struct cxgbi_sock *csk, struct sk_buff *skb, int dlen, |
---|
| 714 | + int len, u32 credits, int compl) |
---|
| 715 | +{ |
---|
| 716 | + struct cxgbi_device *cdev = csk->cdev; |
---|
| 717 | + struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev); |
---|
642 | 718 | struct fw_ofld_tx_data_wr *req; |
---|
643 | | - unsigned int submode = cxgbi_skcb_ulp_mode(skb) & 3; |
---|
644 | | - unsigned int wr_ulp_mode = 0, val; |
---|
645 | | - bool imm = is_ofld_imm(skb); |
---|
| 719 | + struct cpl_tx_data_iso *cpl; |
---|
| 720 | + u32 submode = cxgbi_skcb_tx_ulp_mode(skb) & 0x3; |
---|
| 721 | + u32 wr_ulp_mode = 0; |
---|
| 722 | + u32 hdr_size = sizeof(*req); |
---|
| 723 | + u32 opcode = FW_OFLD_TX_DATA_WR; |
---|
| 724 | + u32 immlen = 0; |
---|
| 725 | + u32 force = is_t5(lldi->adapter_type) ? TX_FORCE_V(!submode) : |
---|
| 726 | + T6_TX_FORCE_F; |
---|
646 | 727 | |
---|
647 | | - req = __skb_push(skb, sizeof(*req)); |
---|
648 | | - |
---|
649 | | - if (imm) { |
---|
650 | | - req->op_to_immdlen = htonl(FW_WR_OP_V(FW_OFLD_TX_DATA_WR) | |
---|
651 | | - FW_WR_COMPL_F | |
---|
652 | | - FW_WR_IMMDLEN_V(dlen)); |
---|
653 | | - req->flowid_len16 = htonl(FW_WR_FLOWID_V(csk->tid) | |
---|
654 | | - FW_WR_LEN16_V(credits)); |
---|
655 | | - } else { |
---|
656 | | - req->op_to_immdlen = |
---|
657 | | - cpu_to_be32(FW_WR_OP_V(FW_OFLD_TX_DATA_WR) | |
---|
658 | | - FW_WR_COMPL_F | |
---|
659 | | - FW_WR_IMMDLEN_V(0)); |
---|
660 | | - req->flowid_len16 = |
---|
661 | | - cpu_to_be32(FW_WR_FLOWID_V(csk->tid) | |
---|
662 | | - FW_WR_LEN16_V(credits)); |
---|
| 728 | + if (cxgbi_skcb_test_flag(skb, SKCBF_TX_ISO)) { |
---|
| 729 | + hdr_size += sizeof(struct cpl_tx_data_iso); |
---|
| 730 | + opcode = FW_ISCSI_TX_DATA_WR; |
---|
| 731 | + immlen += sizeof(struct cpl_tx_data_iso); |
---|
| 732 | + submode |= 8; |
---|
663 | 733 | } |
---|
| 734 | + |
---|
| 735 | + if (is_ofld_imm(skb)) |
---|
| 736 | + immlen += dlen; |
---|
| 737 | + |
---|
| 738 | + req = (struct fw_ofld_tx_data_wr *)__skb_push(skb, hdr_size); |
---|
| 739 | + req->op_to_immdlen = cpu_to_be32(FW_WR_OP_V(opcode) | |
---|
| 740 | + FW_WR_COMPL_V(compl) | |
---|
| 741 | + FW_WR_IMMDLEN_V(immlen)); |
---|
| 742 | + req->flowid_len16 = cpu_to_be32(FW_WR_FLOWID_V(csk->tid) | |
---|
| 743 | + FW_WR_LEN16_V(credits)); |
---|
| 744 | + req->plen = cpu_to_be32(len); |
---|
| 745 | + cpl = (struct cpl_tx_data_iso *)(req + 1); |
---|
| 746 | + |
---|
| 747 | + if (likely(cxgbi_skcb_test_flag(skb, SKCBF_TX_ISO))) |
---|
| 748 | + cxgb4i_make_tx_iso_cpl(skb, cpl); |
---|
| 749 | + |
---|
664 | 750 | if (submode) |
---|
665 | 751 | wr_ulp_mode = FW_OFLD_TX_DATA_WR_ULPMODE_V(ULP2_MODE_ISCSI) | |
---|
666 | | - FW_OFLD_TX_DATA_WR_ULPSUBMODE_V(submode); |
---|
667 | | - val = skb_peek(&csk->write_queue) ? 0 : 1; |
---|
668 | | - req->tunnel_to_proxy = htonl(wr_ulp_mode | |
---|
669 | | - FW_OFLD_TX_DATA_WR_SHOVE_V(val)); |
---|
670 | | - req->plen = htonl(len); |
---|
| 752 | + FW_OFLD_TX_DATA_WR_ULPSUBMODE_V(submode); |
---|
| 753 | + |
---|
| 754 | + req->tunnel_to_proxy = cpu_to_be32(wr_ulp_mode | force | |
---|
| 755 | + FW_OFLD_TX_DATA_WR_SHOVE_V(1U)); |
---|
| 756 | + |
---|
671 | 757 | if (!cxgbi_sock_flag(csk, CTPF_TX_DATA_SENT)) |
---|
672 | 758 | cxgbi_sock_set_flag(csk, CTPF_TX_DATA_SENT); |
---|
673 | 759 | } |
---|
.. | .. |
---|
685 | 771 | if (unlikely(csk->state < CTP_ESTABLISHED || |
---|
686 | 772 | csk->state == CTP_CLOSE_WAIT_1 || csk->state >= CTP_ABORTING)) { |
---|
687 | 773 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK | |
---|
688 | | - 1 << CXGBI_DBG_PDU_TX, |
---|
689 | | - "csk 0x%p,%u,0x%lx,%u, in closing state.\n", |
---|
690 | | - csk, csk->state, csk->flags, csk->tid); |
---|
| 774 | + 1 << CXGBI_DBG_PDU_TX, |
---|
| 775 | + "csk 0x%p,%u,0x%lx,%u, in closing state.\n", |
---|
| 776 | + csk, csk->state, csk->flags, csk->tid); |
---|
691 | 777 | return 0; |
---|
692 | 778 | } |
---|
693 | 779 | |
---|
694 | | - while (csk->wr_cred && (skb = skb_peek(&csk->write_queue)) != NULL) { |
---|
695 | | - int dlen = skb->len; |
---|
696 | | - int len = skb->len; |
---|
697 | | - unsigned int credits_needed; |
---|
698 | | - int flowclen16 = 0; |
---|
| 780 | + while (csk->wr_cred && ((skb = skb_peek(&csk->write_queue)) != NULL)) { |
---|
| 781 | + struct cxgbi_iso_info *iso_cpl; |
---|
| 782 | + u32 dlen = skb->len; |
---|
| 783 | + u32 len = skb->len; |
---|
| 784 | + u32 iso_cpl_len = 0; |
---|
| 785 | + u32 flowclen16 = 0; |
---|
| 786 | + u32 credits_needed; |
---|
| 787 | + u32 num_pdu = 1, hdr_len; |
---|
699 | 788 | |
---|
700 | | - skb_reset_transport_header(skb); |
---|
| 789 | + if (cxgbi_skcb_test_flag(skb, SKCBF_TX_ISO)) |
---|
| 790 | + iso_cpl_len = sizeof(struct cpl_tx_data_iso); |
---|
| 791 | + |
---|
701 | 792 | if (is_ofld_imm(skb)) |
---|
702 | | - credits_needed = DIV_ROUND_UP(dlen, 16); |
---|
| 793 | + credits_needed = DIV_ROUND_UP(dlen + iso_cpl_len, 16); |
---|
703 | 794 | else |
---|
704 | | - credits_needed = DIV_ROUND_UP( |
---|
705 | | - 8 * calc_tx_flits_ofld(skb), |
---|
706 | | - 16); |
---|
| 795 | + credits_needed = |
---|
| 796 | + DIV_ROUND_UP((8 * calc_tx_flits_ofld(skb)) + |
---|
| 797 | + iso_cpl_len, 16); |
---|
707 | 798 | |
---|
708 | 799 | if (likely(cxgbi_skcb_test_flag(skb, SKCBF_TX_NEED_HDR))) |
---|
709 | | - credits_needed += DIV_ROUND_UP( |
---|
710 | | - sizeof(struct fw_ofld_tx_data_wr), |
---|
711 | | - 16); |
---|
| 800 | + credits_needed += |
---|
| 801 | + DIV_ROUND_UP(sizeof(struct fw_ofld_tx_data_wr), 16); |
---|
712 | 802 | |
---|
713 | 803 | /* |
---|
714 | 804 | * Assumes the initial credits is large enough to support |
---|
.. | .. |
---|
723 | 813 | |
---|
724 | 814 | if (csk->wr_cred < credits_needed) { |
---|
725 | 815 | log_debug(1 << CXGBI_DBG_PDU_TX, |
---|
726 | | - "csk 0x%p, skb %u/%u, wr %d < %u.\n", |
---|
727 | | - csk, skb->len, skb->data_len, |
---|
728 | | - credits_needed, csk->wr_cred); |
---|
| 816 | + "csk 0x%p, skb %u/%u, wr %d < %u.\n", |
---|
| 817 | + csk, skb->len, skb->data_len, |
---|
| 818 | + credits_needed, csk->wr_cred); |
---|
| 819 | + |
---|
| 820 | + csk->no_tx_credits++; |
---|
729 | 821 | break; |
---|
730 | 822 | } |
---|
| 823 | + |
---|
| 824 | + csk->no_tx_credits = 0; |
---|
| 825 | + |
---|
731 | 826 | __skb_unlink(skb, &csk->write_queue); |
---|
732 | 827 | set_wr_txq(skb, CPL_PRIORITY_DATA, csk->port_id); |
---|
733 | | - skb->csum = credits_needed + flowclen16; |
---|
| 828 | + skb->csum = (__force __wsum)(credits_needed + flowclen16); |
---|
734 | 829 | csk->wr_cred -= credits_needed; |
---|
735 | 830 | csk->wr_una_cred += credits_needed; |
---|
736 | 831 | cxgbi_sock_enqueue_wr(csk, skb); |
---|
.. | .. |
---|
740 | 835 | csk, skb->len, skb->data_len, credits_needed, |
---|
741 | 836 | csk->wr_cred, csk->wr_una_cred); |
---|
742 | 837 | |
---|
| 838 | + if (!req_completion && |
---|
| 839 | + ((csk->wr_una_cred >= (csk->wr_max_cred / 2)) || |
---|
| 840 | + after(csk->write_seq, (csk->snd_una + csk->snd_win / 2)))) |
---|
| 841 | + req_completion = 1; |
---|
| 842 | + |
---|
743 | 843 | if (likely(cxgbi_skcb_test_flag(skb, SKCBF_TX_NEED_HDR))) { |
---|
744 | | - len += cxgbi_ulp_extra_len(cxgbi_skcb_ulp_mode(skb)); |
---|
745 | | - make_tx_data_wr(csk, skb, dlen, len, credits_needed, |
---|
746 | | - req_completion); |
---|
| 844 | + u32 ulp_mode = cxgbi_skcb_tx_ulp_mode(skb); |
---|
| 845 | + |
---|
| 846 | + if (cxgbi_skcb_test_flag(skb, SKCBF_TX_ISO)) { |
---|
| 847 | + iso_cpl = (struct cxgbi_iso_info *)skb->head; |
---|
| 848 | + num_pdu = iso_cpl->num_pdu; |
---|
| 849 | + hdr_len = cxgbi_skcb_tx_iscsi_hdrlen(skb); |
---|
| 850 | + len += (cxgbi_ulp_extra_len(ulp_mode) * num_pdu) + |
---|
| 851 | + (hdr_len * (num_pdu - 1)); |
---|
| 852 | + } else { |
---|
| 853 | + len += cxgbi_ulp_extra_len(ulp_mode); |
---|
| 854 | + } |
---|
| 855 | + |
---|
| 856 | + cxgb4i_make_tx_data_wr(csk, skb, dlen, len, |
---|
| 857 | + credits_needed, req_completion); |
---|
747 | 858 | csk->snd_nxt += len; |
---|
748 | 859 | cxgbi_skcb_clear_flag(skb, SKCBF_TX_NEED_HDR); |
---|
749 | 860 | } else if (cxgbi_skcb_test_flag(skb, SKCBF_TX_FLAG_COMPL) && |
---|
750 | 861 | (csk->wr_una_cred >= (csk->wr_max_cred / 2))) { |
---|
751 | 862 | struct cpl_close_con_req *req = |
---|
752 | 863 | (struct cpl_close_con_req *)skb->data; |
---|
753 | | - req->wr.wr_hi |= htonl(FW_WR_COMPL_F); |
---|
| 864 | + |
---|
| 865 | + req->wr.wr_hi |= cpu_to_be32(FW_WR_COMPL_F); |
---|
754 | 866 | } |
---|
| 867 | + |
---|
755 | 868 | total_size += skb->truesize; |
---|
756 | 869 | t4_set_arp_err_handler(skb, csk, arp_failure_skb_discard); |
---|
757 | 870 | |
---|
758 | 871 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_PDU_TX, |
---|
759 | | - "csk 0x%p,%u,0x%lx,%u, skb 0x%p, %u.\n", |
---|
760 | | - csk, csk->state, csk->flags, csk->tid, skb, len); |
---|
761 | | - |
---|
| 872 | + "csk 0x%p,%u,0x%lx,%u, skb 0x%p, %u.\n", |
---|
| 873 | + csk, csk->state, csk->flags, csk->tid, skb, len); |
---|
762 | 874 | cxgb4_l2t_send(csk->cdev->ports[csk->port_id], skb, csk->l2t); |
---|
763 | 875 | } |
---|
764 | 876 | return total_size; |
---|
.. | .. |
---|
1022 | 1134 | int *need_rst) |
---|
1023 | 1135 | { |
---|
1024 | 1136 | switch (abort_reason) { |
---|
1025 | | - case CPL_ERR_BAD_SYN: /* fall through */ |
---|
| 1137 | + case CPL_ERR_BAD_SYN: |
---|
1026 | 1138 | case CPL_ERR_CONN_RESET: |
---|
1027 | 1139 | return csk->state > CTP_ESTABLISHED ? |
---|
1028 | 1140 | -EPIPE : -ECONNRESET; |
---|
.. | .. |
---|
1096 | 1208 | if (!csk) |
---|
1097 | 1209 | goto rel_skb; |
---|
1098 | 1210 | |
---|
1099 | | - if (csk) |
---|
1100 | | - pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u, status %u.\n", |
---|
1101 | | - (&csk->saddr), (&csk->daddr), csk, |
---|
1102 | | - csk->state, csk->flags, csk->tid, rpl->status); |
---|
| 1211 | + pr_info_ipaddr("csk 0x%p,%u,0x%lx,%u, status %u.\n", |
---|
| 1212 | + (&csk->saddr), (&csk->daddr), csk, |
---|
| 1213 | + csk->state, csk->flags, csk->tid, rpl->status); |
---|
1103 | 1214 | |
---|
1104 | 1215 | if (rpl->status == CPL_ERR_ABORT_FAILED) |
---|
1105 | 1216 | goto rel_skb; |
---|
.. | .. |
---|
1179 | 1290 | csk->skb_ulp_lhdr = skb; |
---|
1180 | 1291 | cxgbi_skcb_set_flag(skb, SKCBF_RX_HDR); |
---|
1181 | 1292 | |
---|
1182 | | - if (cxgbi_skcb_tcp_seq(skb) != csk->rcv_nxt) { |
---|
| 1293 | + if ((CHELSIO_CHIP_VERSION(lldi->adapter_type) <= CHELSIO_T5) && |
---|
| 1294 | + (cxgbi_skcb_tcp_seq(skb) != csk->rcv_nxt)) { |
---|
1183 | 1295 | pr_info("tid %u, CPL_ISCSI_HDR, bad seq, 0x%x/0x%x.\n", |
---|
1184 | 1296 | csk->tid, cxgbi_skcb_tcp_seq(skb), |
---|
1185 | 1297 | csk->rcv_nxt); |
---|
.. | .. |
---|
1606 | 1718 | csk->dst = NULL; |
---|
1607 | 1719 | } |
---|
1608 | 1720 | |
---|
| 1721 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 1722 | +static inline u8 get_iscsi_dcb_state(struct net_device *ndev) |
---|
| 1723 | +{ |
---|
| 1724 | + return ndev->dcbnl_ops->getstate(ndev); |
---|
| 1725 | +} |
---|
| 1726 | + |
---|
| 1727 | +static int select_priority(int pri_mask) |
---|
| 1728 | +{ |
---|
| 1729 | + if (!pri_mask) |
---|
| 1730 | + return 0; |
---|
| 1731 | + return (ffs(pri_mask) - 1); |
---|
| 1732 | +} |
---|
| 1733 | + |
---|
| 1734 | +static u8 get_iscsi_dcb_priority(struct net_device *ndev) |
---|
| 1735 | +{ |
---|
| 1736 | + int rv; |
---|
| 1737 | + u8 caps; |
---|
| 1738 | + |
---|
| 1739 | + struct dcb_app iscsi_dcb_app = { |
---|
| 1740 | + .protocol = 3260 |
---|
| 1741 | + }; |
---|
| 1742 | + |
---|
| 1743 | + rv = (int)ndev->dcbnl_ops->getcap(ndev, DCB_CAP_ATTR_DCBX, &caps); |
---|
| 1744 | + if (rv) |
---|
| 1745 | + return 0; |
---|
| 1746 | + |
---|
| 1747 | + if (caps & DCB_CAP_DCBX_VER_IEEE) { |
---|
| 1748 | + iscsi_dcb_app.selector = IEEE_8021QAZ_APP_SEL_STREAM; |
---|
| 1749 | + rv = dcb_ieee_getapp_mask(ndev, &iscsi_dcb_app); |
---|
| 1750 | + if (!rv) { |
---|
| 1751 | + iscsi_dcb_app.selector = IEEE_8021QAZ_APP_SEL_ANY; |
---|
| 1752 | + rv = dcb_ieee_getapp_mask(ndev, &iscsi_dcb_app); |
---|
| 1753 | + } |
---|
| 1754 | + } else if (caps & DCB_CAP_DCBX_VER_CEE) { |
---|
| 1755 | + iscsi_dcb_app.selector = DCB_APP_IDTYPE_PORTNUM; |
---|
| 1756 | + rv = dcb_getapp(ndev, &iscsi_dcb_app); |
---|
| 1757 | + } |
---|
| 1758 | + |
---|
| 1759 | + log_debug(1 << CXGBI_DBG_ISCSI, |
---|
| 1760 | + "iSCSI priority is set to %u\n", select_priority(rv)); |
---|
| 1761 | + return select_priority(rv); |
---|
| 1762 | +} |
---|
| 1763 | +#endif |
---|
| 1764 | + |
---|
1609 | 1765 | static int init_act_open(struct cxgbi_sock *csk) |
---|
1610 | 1766 | { |
---|
1611 | 1767 | struct cxgbi_device *cdev = csk->cdev; |
---|
.. | .. |
---|
1619 | 1775 | unsigned int size, size6; |
---|
1620 | 1776 | unsigned int linkspeed; |
---|
1621 | 1777 | unsigned int rcv_winf, snd_winf; |
---|
1622 | | - |
---|
| 1778 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 1779 | + u8 priority = 0; |
---|
| 1780 | +#endif |
---|
1623 | 1781 | log_debug(1 << CXGBI_DBG_TOE | 1 << CXGBI_DBG_SOCK, |
---|
1624 | 1782 | "csk 0x%p,%u,0x%lx,%u.\n", |
---|
1625 | 1783 | csk, csk->state, csk->flags, csk->tid); |
---|
.. | .. |
---|
1653 | 1811 | cxgbi_sock_set_flag(csk, CTPF_HAS_ATID); |
---|
1654 | 1812 | cxgbi_sock_get(csk); |
---|
1655 | 1813 | |
---|
| 1814 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 1815 | + if (get_iscsi_dcb_state(ndev)) |
---|
| 1816 | + priority = get_iscsi_dcb_priority(ndev); |
---|
| 1817 | + |
---|
| 1818 | + csk->dcb_priority = priority; |
---|
| 1819 | + csk->l2t = cxgb4_l2t_get(lldi->l2t, n, ndev, priority); |
---|
| 1820 | +#else |
---|
1656 | 1821 | csk->l2t = cxgb4_l2t_get(lldi->l2t, n, ndev, 0); |
---|
| 1822 | +#endif |
---|
1657 | 1823 | if (!csk->l2t) { |
---|
1658 | 1824 | pr_err("%s, cannot alloc l2t.\n", ndev->name); |
---|
1659 | 1825 | goto rel_resource_without_clip; |
---|
.. | .. |
---|
1692 | 1858 | csk->mtu = dst_mtu(csk->dst); |
---|
1693 | 1859 | cxgb4_best_mtu(lldi->mtus, csk->mtu, &csk->mss_idx); |
---|
1694 | 1860 | csk->tx_chan = cxgb4_port_chan(ndev); |
---|
1695 | | - csk->smac_idx = cxgb4_tp_smt_idx(lldi->adapter_type, |
---|
1696 | | - cxgb4_port_viid(ndev)); |
---|
| 1861 | + csk->smac_idx = ((struct port_info *)netdev_priv(ndev))->smt_idx; |
---|
1697 | 1862 | step = lldi->ntxq / lldi->nchan; |
---|
1698 | 1863 | csk->txq_idx = cxgb4_port_idx(ndev) * step; |
---|
1699 | 1864 | step = lldi->nrxq / lldi->nchan; |
---|
.. | .. |
---|
1988 | 2153 | struct cxgb4_lld_info *lldi = cxgbi_cdev_priv(cdev); |
---|
1989 | 2154 | struct net_device *ndev = cdev->ports[0]; |
---|
1990 | 2155 | struct cxgbi_tag_format tformat; |
---|
1991 | | - unsigned int ppmax; |
---|
1992 | | - int i; |
---|
| 2156 | + int i, err; |
---|
1993 | 2157 | |
---|
1994 | 2158 | if (!lldi->vr->iscsi.size) { |
---|
1995 | 2159 | pr_warn("%s, iscsi NOT enabled, check config!\n", ndev->name); |
---|
.. | .. |
---|
1997 | 2161 | } |
---|
1998 | 2162 | |
---|
1999 | 2163 | cdev->flags |= CXGBI_FLAG_USE_PPOD_OFLDQ; |
---|
2000 | | - ppmax = lldi->vr->iscsi.size >> PPOD_SIZE_SHIFT; |
---|
2001 | 2164 | |
---|
2002 | 2165 | memset(&tformat, 0, sizeof(struct cxgbi_tag_format)); |
---|
2003 | 2166 | for (i = 0; i < 4; i++) |
---|
.. | .. |
---|
2005 | 2168 | & 0xF; |
---|
2006 | 2169 | cxgbi_tagmask_check(lldi->iscsi_tagmask, &tformat); |
---|
2007 | 2170 | |
---|
2008 | | - cxgbi_ddp_ppm_setup(lldi->iscsi_ppm, cdev, &tformat, ppmax, |
---|
2009 | | - lldi->iscsi_llimit, lldi->vr->iscsi.start, 2); |
---|
| 2171 | + pr_info("iscsi_edram.start 0x%x iscsi_edram.size 0x%x", |
---|
| 2172 | + lldi->vr->ppod_edram.start, lldi->vr->ppod_edram.size); |
---|
| 2173 | + |
---|
| 2174 | + err = cxgbi_ddp_ppm_setup(lldi->iscsi_ppm, cdev, &tformat, |
---|
| 2175 | + lldi->vr->iscsi.size, lldi->iscsi_llimit, |
---|
| 2176 | + lldi->vr->iscsi.start, 2, |
---|
| 2177 | + lldi->vr->ppod_edram.start, |
---|
| 2178 | + lldi->vr->ppod_edram.size); |
---|
| 2179 | + |
---|
| 2180 | + if (err < 0) |
---|
| 2181 | + return err; |
---|
2010 | 2182 | |
---|
2011 | 2183 | cdev->csk_ddp_setup_digest = ddp_setup_conn_digest; |
---|
2012 | 2184 | cdev->csk_ddp_setup_pgidx = ddp_setup_conn_pgidx; |
---|
.. | .. |
---|
2020 | 2192 | return 0; |
---|
2021 | 2193 | } |
---|
2022 | 2194 | |
---|
| 2195 | +static bool is_memfree(struct adapter *adap) |
---|
| 2196 | +{ |
---|
| 2197 | + u32 io; |
---|
| 2198 | + |
---|
| 2199 | + io = t4_read_reg(adap, MA_TARGET_MEM_ENABLE_A); |
---|
| 2200 | + if (is_t5(adap->params.chip)) { |
---|
| 2201 | + if ((io & EXT_MEM0_ENABLE_F) || (io & EXT_MEM1_ENABLE_F)) |
---|
| 2202 | + return false; |
---|
| 2203 | + } else if (io & EXT_MEM_ENABLE_F) { |
---|
| 2204 | + return false; |
---|
| 2205 | + } |
---|
| 2206 | + |
---|
| 2207 | + return true; |
---|
| 2208 | +} |
---|
| 2209 | + |
---|
2023 | 2210 | static void *t4_uld_add(const struct cxgb4_lld_info *lldi) |
---|
2024 | 2211 | { |
---|
2025 | 2212 | struct cxgbi_device *cdev; |
---|
2026 | 2213 | struct port_info *pi; |
---|
| 2214 | + struct net_device *ndev; |
---|
| 2215 | + struct adapter *adap; |
---|
| 2216 | + struct tid_info *t; |
---|
| 2217 | + u32 max_cmds = CXGB4I_SCSI_HOST_QDEPTH; |
---|
| 2218 | + u32 max_conn = CXGBI_MAX_CONN; |
---|
2027 | 2219 | int i, rc; |
---|
2028 | 2220 | |
---|
2029 | 2221 | cdev = cxgbi_device_register(sizeof(*lldi), lldi->nports); |
---|
.. | .. |
---|
2054 | 2246 | cdev->itp = &cxgb4i_iscsi_transport; |
---|
2055 | 2247 | cdev->owner = THIS_MODULE; |
---|
2056 | 2248 | |
---|
2057 | | - cdev->pfvf = FW_VIID_PFN_G(cxgb4_port_viid(lldi->ports[0])) |
---|
2058 | | - << FW_VIID_PFN_S; |
---|
| 2249 | + cdev->pfvf = FW_PFVF_CMD_PFN_V(lldi->pf); |
---|
2059 | 2250 | pr_info("cdev 0x%p,%s, pfvf %u.\n", |
---|
2060 | 2251 | cdev, lldi->ports[0]->name, cdev->pfvf); |
---|
2061 | 2252 | |
---|
2062 | 2253 | rc = cxgb4i_ddp_init(cdev); |
---|
2063 | 2254 | if (rc) { |
---|
2064 | | - pr_info("t4 0x%p ddp init failed.\n", cdev); |
---|
| 2255 | + pr_info("t4 0x%p ddp init failed %d.\n", cdev, rc); |
---|
2065 | 2256 | goto err_out; |
---|
2066 | 2257 | } |
---|
| 2258 | + |
---|
| 2259 | + ndev = cdev->ports[0]; |
---|
| 2260 | + adap = netdev2adap(ndev); |
---|
| 2261 | + if (adap) { |
---|
| 2262 | + t = &adap->tids; |
---|
| 2263 | + if (t->ntids <= CXGBI_MAX_CONN) |
---|
| 2264 | + max_conn = t->ntids; |
---|
| 2265 | + |
---|
| 2266 | + if (is_memfree(adap)) { |
---|
| 2267 | + cdev->flags |= CXGBI_FLAG_DEV_ISO_OFF; |
---|
| 2268 | + max_cmds = CXGB4I_SCSI_HOST_QDEPTH >> 2; |
---|
| 2269 | + |
---|
| 2270 | + pr_info("%s: 0x%p, tid %u, SO adapter.\n", |
---|
| 2271 | + ndev->name, cdev, t->ntids); |
---|
| 2272 | + } |
---|
| 2273 | + } else { |
---|
| 2274 | + pr_info("%s, 0x%p, NO adapter struct.\n", ndev->name, cdev); |
---|
| 2275 | + } |
---|
| 2276 | + |
---|
| 2277 | + /* ISO is enabled in T5/T6 firmware version >= 1.13.43.0 */ |
---|
| 2278 | + if (!is_t4(lldi->adapter_type) && |
---|
| 2279 | + (lldi->fw_vers >= 0x10d2b00) && |
---|
| 2280 | + !(cdev->flags & CXGBI_FLAG_DEV_ISO_OFF)) |
---|
| 2281 | + cdev->skb_iso_txhdr = sizeof(struct cpl_tx_data_iso); |
---|
| 2282 | + |
---|
2067 | 2283 | rc = cxgb4i_ofld_init(cdev); |
---|
2068 | 2284 | if (rc) { |
---|
2069 | 2285 | pr_info("t4 0x%p ofld init failed.\n", cdev); |
---|
2070 | 2286 | goto err_out; |
---|
2071 | 2287 | } |
---|
2072 | 2288 | |
---|
2073 | | - rc = cxgbi_hbas_add(cdev, CXGB4I_MAX_LUN, CXGBI_MAX_CONN, |
---|
2074 | | - &cxgb4i_host_template, cxgb4i_stt); |
---|
| 2289 | + cxgb4i_host_template.can_queue = max_cmds; |
---|
| 2290 | + rc = cxgbi_hbas_add(cdev, CXGB4I_MAX_LUN, max_conn, |
---|
| 2291 | + &cxgb4i_host_template, cxgb4i_stt); |
---|
2075 | 2292 | if (rc) |
---|
2076 | 2293 | goto err_out; |
---|
2077 | 2294 | |
---|
.. | .. |
---|
2158 | 2375 | return 0; |
---|
2159 | 2376 | } |
---|
2160 | 2377 | |
---|
| 2378 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 2379 | +static int |
---|
| 2380 | +cxgb4_dcb_change_notify(struct notifier_block *self, unsigned long val, |
---|
| 2381 | + void *data) |
---|
| 2382 | +{ |
---|
| 2383 | + int i, port = 0xFF; |
---|
| 2384 | + struct net_device *ndev; |
---|
| 2385 | + struct cxgbi_device *cdev = NULL; |
---|
| 2386 | + struct dcb_app_type *iscsi_app = data; |
---|
| 2387 | + struct cxgbi_ports_map *pmap; |
---|
| 2388 | + u8 priority; |
---|
| 2389 | + |
---|
| 2390 | + if (iscsi_app->dcbx & DCB_CAP_DCBX_VER_IEEE) { |
---|
| 2391 | + if ((iscsi_app->app.selector != IEEE_8021QAZ_APP_SEL_STREAM) && |
---|
| 2392 | + (iscsi_app->app.selector != IEEE_8021QAZ_APP_SEL_ANY)) |
---|
| 2393 | + return NOTIFY_DONE; |
---|
| 2394 | + |
---|
| 2395 | + priority = iscsi_app->app.priority; |
---|
| 2396 | + } else if (iscsi_app->dcbx & DCB_CAP_DCBX_VER_CEE) { |
---|
| 2397 | + if (iscsi_app->app.selector != DCB_APP_IDTYPE_PORTNUM) |
---|
| 2398 | + return NOTIFY_DONE; |
---|
| 2399 | + |
---|
| 2400 | + if (!iscsi_app->app.priority) |
---|
| 2401 | + return NOTIFY_DONE; |
---|
| 2402 | + |
---|
| 2403 | + priority = ffs(iscsi_app->app.priority) - 1; |
---|
| 2404 | + } else { |
---|
| 2405 | + return NOTIFY_DONE; |
---|
| 2406 | + } |
---|
| 2407 | + |
---|
| 2408 | + if (iscsi_app->app.protocol != 3260) |
---|
| 2409 | + return NOTIFY_DONE; |
---|
| 2410 | + |
---|
| 2411 | + log_debug(1 << CXGBI_DBG_ISCSI, "iSCSI priority for ifid %d is %u\n", |
---|
| 2412 | + iscsi_app->ifindex, priority); |
---|
| 2413 | + |
---|
| 2414 | + ndev = dev_get_by_index(&init_net, iscsi_app->ifindex); |
---|
| 2415 | + if (!ndev) |
---|
| 2416 | + return NOTIFY_DONE; |
---|
| 2417 | + |
---|
| 2418 | + cdev = cxgbi_device_find_by_netdev_rcu(ndev, &port); |
---|
| 2419 | + |
---|
| 2420 | + dev_put(ndev); |
---|
| 2421 | + if (!cdev) |
---|
| 2422 | + return NOTIFY_DONE; |
---|
| 2423 | + |
---|
| 2424 | + pmap = &cdev->pmap; |
---|
| 2425 | + |
---|
| 2426 | + for (i = 0; i < pmap->used; i++) { |
---|
| 2427 | + if (pmap->port_csk[i]) { |
---|
| 2428 | + struct cxgbi_sock *csk = pmap->port_csk[i]; |
---|
| 2429 | + |
---|
| 2430 | + if (csk->dcb_priority != priority) { |
---|
| 2431 | + iscsi_conn_failure(csk->user_data, |
---|
| 2432 | + ISCSI_ERR_CONN_FAILED); |
---|
| 2433 | + pr_info("Restarting iSCSI connection %p with " |
---|
| 2434 | + "priority %u->%u.\n", csk, |
---|
| 2435 | + csk->dcb_priority, priority); |
---|
| 2436 | + } |
---|
| 2437 | + } |
---|
| 2438 | + } |
---|
| 2439 | + return NOTIFY_OK; |
---|
| 2440 | +} |
---|
| 2441 | +#endif |
---|
| 2442 | + |
---|
2161 | 2443 | static int __init cxgb4i_init_module(void) |
---|
2162 | 2444 | { |
---|
2163 | 2445 | int rc; |
---|
.. | .. |
---|
2169 | 2451 | return rc; |
---|
2170 | 2452 | cxgb4_register_uld(CXGB4_ULD_ISCSI, &cxgb4i_uld_info); |
---|
2171 | 2453 | |
---|
| 2454 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 2455 | + pr_info("%s dcb enabled.\n", DRV_MODULE_NAME); |
---|
| 2456 | + register_dcbevent_notifier(&cxgb4_dcb_change); |
---|
| 2457 | +#endif |
---|
2172 | 2458 | return 0; |
---|
2173 | 2459 | } |
---|
2174 | 2460 | |
---|
2175 | 2461 | static void __exit cxgb4i_exit_module(void) |
---|
2176 | 2462 | { |
---|
| 2463 | +#ifdef CONFIG_CHELSIO_T4_DCB |
---|
| 2464 | + unregister_dcbevent_notifier(&cxgb4_dcb_change); |
---|
| 2465 | +#endif |
---|
2177 | 2466 | cxgb4_unregister_uld(CXGB4_ULD_ISCSI); |
---|
2178 | 2467 | cxgbi_device_unregister_all(CXGBI_FLAG_DEV_T4); |
---|
2179 | 2468 | cxgbi_iscsi_cleanup(&cxgb4i_iscsi_transport, &cxgb4i_stt); |
---|