diff options
Diffstat (limited to 'drivers/net/benet')
-rw-r--r-- | drivers/net/benet/be.h | 23 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 39 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 20 | ||||
-rw-r--r-- | drivers/net/benet/be_hw.h | 41 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 279 |
5 files changed, 252 insertions, 150 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h index 4ac0d72660f..62af70716f8 100644 --- a/drivers/net/benet/be.h +++ b/drivers/net/benet/be.h | |||
@@ -67,7 +67,7 @@ static inline char *nic_name(struct pci_dev *pdev) | |||
67 | } | 67 | } |
68 | 68 | ||
69 | /* Number of bytes of an RX frame that are copied to skb->data */ | 69 | /* Number of bytes of an RX frame that are copied to skb->data */ |
70 | #define BE_HDR_LEN 64 | 70 | #define BE_HDR_LEN ((u16) 64) |
71 | #define BE_MAX_JUMBO_FRAME_SIZE 9018 | 71 | #define BE_MAX_JUMBO_FRAME_SIZE 9018 |
72 | #define BE_MIN_MTU 256 | 72 | #define BE_MIN_MTU 256 |
73 | 73 | ||
@@ -211,10 +211,30 @@ struct be_rx_stats { | |||
211 | u32 rx_fps; /* Rx frags per second */ | 211 | u32 rx_fps; /* Rx frags per second */ |
212 | }; | 212 | }; |
213 | 213 | ||
214 | struct be_rx_compl_info { | ||
215 | u32 rss_hash; | ||
216 | u16 vid; | ||
217 | u16 pkt_size; | ||
218 | u16 rxq_idx; | ||
219 | u16 mac_id; | ||
220 | u8 vlanf; | ||
221 | u8 num_rcvd; | ||
222 | u8 err; | ||
223 | u8 ipf; | ||
224 | u8 tcpf; | ||
225 | u8 udpf; | ||
226 | u8 ip_csum; | ||
227 | u8 l4_csum; | ||
228 | u8 ipv6; | ||
229 | u8 vtm; | ||
230 | u8 pkt_type; | ||
231 | }; | ||
232 | |||
214 | struct be_rx_obj { | 233 | struct be_rx_obj { |
215 | struct be_adapter *adapter; | 234 | struct be_adapter *adapter; |
216 | struct be_queue_info q; | 235 | struct be_queue_info q; |
217 | struct be_queue_info cq; | 236 | struct be_queue_info cq; |
237 | struct be_rx_compl_info rxcp; | ||
218 | struct be_rx_page_info page_info_tbl[RX_Q_LEN]; | 238 | struct be_rx_page_info page_info_tbl[RX_Q_LEN]; |
219 | struct be_eq_obj rx_eq; | 239 | struct be_eq_obj rx_eq; |
220 | struct be_rx_stats stats; | 240 | struct be_rx_stats stats; |
@@ -312,6 +332,7 @@ struct be_adapter { | |||
312 | u32 flash_status; | 332 | u32 flash_status; |
313 | struct completion flash_compl; | 333 | struct completion flash_compl; |
314 | 334 | ||
335 | bool be3_native; | ||
315 | bool sriov_enabled; | 336 | bool sriov_enabled; |
316 | struct be_vf_cfg vf_cfg[BE_MAX_VF]; | 337 | struct be_vf_cfg vf_cfg[BE_MAX_VF]; |
317 | u8 is_virtfn; | 338 | u8 is_virtfn; |
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c index cc3a235475b..e1124c89181 100644 --- a/drivers/net/benet/be_cmds.c +++ b/drivers/net/benet/be_cmds.c | |||
@@ -2014,3 +2014,42 @@ err: | |||
2014 | attribs_cmd.dma); | 2014 | attribs_cmd.dma); |
2015 | return status; | 2015 | return status; |
2016 | } | 2016 | } |
2017 | |||
2018 | /* Uses mbox */ | ||
2019 | int be_cmd_check_native_mode(struct be_adapter *adapter) | ||
2020 | { | ||
2021 | struct be_mcc_wrb *wrb; | ||
2022 | struct be_cmd_req_set_func_cap *req; | ||
2023 | int status; | ||
2024 | |||
2025 | if (mutex_lock_interruptible(&adapter->mbox_lock)) | ||
2026 | return -1; | ||
2027 | |||
2028 | wrb = wrb_from_mbox(adapter); | ||
2029 | if (!wrb) { | ||
2030 | status = -EBUSY; | ||
2031 | goto err; | ||
2032 | } | ||
2033 | |||
2034 | req = embedded_payload(wrb); | ||
2035 | |||
2036 | be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0, | ||
2037 | OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP); | ||
2038 | |||
2039 | be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, | ||
2040 | OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP, sizeof(*req)); | ||
2041 | |||
2042 | req->valid_cap_flags = cpu_to_le32(CAPABILITY_SW_TIMESTAMPS | | ||
2043 | CAPABILITY_BE3_NATIVE_ERX_API); | ||
2044 | req->cap_flags = cpu_to_le32(CAPABILITY_BE3_NATIVE_ERX_API); | ||
2045 | |||
2046 | status = be_mbox_notify_wait(adapter); | ||
2047 | if (!status) { | ||
2048 | struct be_cmd_resp_set_func_cap *resp = embedded_payload(wrb); | ||
2049 | adapter->be3_native = le32_to_cpu(resp->cap_flags) & | ||
2050 | CAPABILITY_BE3_NATIVE_ERX_API; | ||
2051 | } | ||
2052 | err: | ||
2053 | mutex_unlock(&adapter->mbox_lock); | ||
2054 | return status; | ||
2055 | } | ||
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h index b4ac3938b29..e41fcbaed00 100644 --- a/drivers/net/benet/be_cmds.h +++ b/drivers/net/benet/be_cmds.h | |||
@@ -190,6 +190,7 @@ struct be_mcc_mailbox { | |||
190 | #define OPCODE_COMMON_GET_BEACON_STATE 70 | 190 | #define OPCODE_COMMON_GET_BEACON_STATE 70 |
191 | #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 | 191 | #define OPCODE_COMMON_READ_TRANSRECV_DATA 73 |
192 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 | 192 | #define OPCODE_COMMON_GET_PHY_DETAILS 102 |
193 | #define OPCODE_COMMON_SET_DRIVER_FUNCTION_CAP 103 | ||
193 | #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 | 194 | #define OPCODE_COMMON_GET_CNTL_ADDITIONAL_ATTRIBUTES 121 |
194 | 195 | ||
195 | #define OPCODE_ETH_RSS_CONFIG 1 | 196 | #define OPCODE_ETH_RSS_CONFIG 1 |
@@ -1042,6 +1043,24 @@ struct be_cmd_resp_cntl_attribs { | |||
1042 | struct mgmt_controller_attrib attribs; | 1043 | struct mgmt_controller_attrib attribs; |
1043 | }; | 1044 | }; |
1044 | 1045 | ||
1046 | /*********************** Set driver function ***********************/ | ||
1047 | #define CAPABILITY_SW_TIMESTAMPS 2 | ||
1048 | #define CAPABILITY_BE3_NATIVE_ERX_API 4 | ||
1049 | |||
1050 | struct be_cmd_req_set_func_cap { | ||
1051 | struct be_cmd_req_hdr hdr; | ||
1052 | u32 valid_cap_flags; | ||
1053 | u32 cap_flags; | ||
1054 | u8 rsvd[212]; | ||
1055 | }; | ||
1056 | |||
1057 | struct be_cmd_resp_set_func_cap { | ||
1058 | struct be_cmd_resp_hdr hdr; | ||
1059 | u32 valid_cap_flags; | ||
1060 | u32 cap_flags; | ||
1061 | u8 rsvd[212]; | ||
1062 | }; | ||
1063 | |||
1045 | extern int be_pci_fnum_get(struct be_adapter *adapter); | 1064 | extern int be_pci_fnum_get(struct be_adapter *adapter); |
1046 | extern int be_cmd_POST(struct be_adapter *adapter); | 1065 | extern int be_cmd_POST(struct be_adapter *adapter); |
1047 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, | 1066 | extern int be_cmd_mac_addr_query(struct be_adapter *adapter, u8 *mac_addr, |
@@ -1128,4 +1147,5 @@ extern int be_cmd_set_qos(struct be_adapter *adapter, u32 bps, u32 domain); | |||
1128 | extern void be_detect_dump_ue(struct be_adapter *adapter); | 1147 | extern void be_detect_dump_ue(struct be_adapter *adapter); |
1129 | extern int be_cmd_get_die_temperature(struct be_adapter *adapter); | 1148 | extern int be_cmd_get_die_temperature(struct be_adapter *adapter); |
1130 | extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); | 1149 | extern int be_cmd_get_cntl_attributes(struct be_adapter *adapter); |
1150 | extern int be_cmd_check_native_mode(struct be_adapter *adapter); | ||
1131 | 1151 | ||
diff --git a/drivers/net/benet/be_hw.h b/drivers/net/benet/be_hw.h index dbe67f353e8..e06aa1567b2 100644 --- a/drivers/net/benet/be_hw.h +++ b/drivers/net/benet/be_hw.h | |||
@@ -301,10 +301,10 @@ struct be_eth_rx_d { | |||
301 | 301 | ||
302 | /* RX Compl Queue Descriptor */ | 302 | /* RX Compl Queue Descriptor */ |
303 | 303 | ||
304 | /* Pseudo amap definition for eth_rx_compl in which each bit of the | 304 | /* Pseudo amap definition for BE2 and BE3 legacy mode eth_rx_compl in which |
305 | * actual structure is defined as a byte: used to calculate | 305 | * each bit of the actual structure is defined as a byte: used to calculate |
306 | * offset/shift/mask of each field */ | 306 | * offset/shift/mask of each field */ |
307 | struct amap_eth_rx_compl { | 307 | struct amap_eth_rx_compl_v0 { |
308 | u8 vlan_tag[16]; /* dword 0 */ | 308 | u8 vlan_tag[16]; /* dword 0 */ |
309 | u8 pktsize[14]; /* dword 0 */ | 309 | u8 pktsize[14]; /* dword 0 */ |
310 | u8 port; /* dword 0 */ | 310 | u8 port; /* dword 0 */ |
@@ -335,6 +335,41 @@ struct amap_eth_rx_compl { | |||
335 | u8 rsshash[32]; /* dword 3 */ | 335 | u8 rsshash[32]; /* dword 3 */ |
336 | } __packed; | 336 | } __packed; |
337 | 337 | ||
338 | /* Pseudo amap definition for BE3 native mode eth_rx_compl in which | ||
339 | * each bit of the actual structure is defined as a byte: used to calculate | ||
340 | * offset/shift/mask of each field */ | ||
341 | struct amap_eth_rx_compl_v1 { | ||
342 | u8 vlan_tag[16]; /* dword 0 */ | ||
343 | u8 pktsize[14]; /* dword 0 */ | ||
344 | u8 vtp; /* dword 0 */ | ||
345 | u8 ip_opt; /* dword 0 */ | ||
346 | u8 err; /* dword 1 */ | ||
347 | u8 rsshp; /* dword 1 */ | ||
348 | u8 ipf; /* dword 1 */ | ||
349 | u8 tcpf; /* dword 1 */ | ||
350 | u8 udpf; /* dword 1 */ | ||
351 | u8 ipcksm; /* dword 1 */ | ||
352 | u8 l4_cksm; /* dword 1 */ | ||
353 | u8 ip_version; /* dword 1 */ | ||
354 | u8 macdst[7]; /* dword 1 */ | ||
355 | u8 rsvd0; /* dword 1 */ | ||
356 | u8 fragndx[10]; /* dword 1 */ | ||
357 | u8 ct[2]; /* dword 1 */ | ||
358 | u8 sw; /* dword 1 */ | ||
359 | u8 numfrags[3]; /* dword 1 */ | ||
360 | u8 rss_flush; /* dword 2 */ | ||
361 | u8 cast_enc[2]; /* dword 2 */ | ||
362 | u8 vtm; /* dword 2 */ | ||
363 | u8 rss_bank; /* dword 2 */ | ||
364 | u8 port[2]; /* dword 2 */ | ||
365 | u8 vntagp; /* dword 2 */ | ||
366 | u8 header_len[8]; /* dword 2 */ | ||
367 | u8 header_split[2]; /* dword 2 */ | ||
368 | u8 rsvd1[13]; /* dword 2 */ | ||
369 | u8 valid; /* dword 2 */ | ||
370 | u8 rsshash[32]; /* dword 3 */ | ||
371 | } __packed; | ||
372 | |||
338 | struct be_eth_rx_compl { | 373 | struct be_eth_rx_compl { |
339 | u32 dw[4]; | 374 | u32 dw[4]; |
340 | }; | 375 | }; |
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c index 68f10781732..3cb5f4e5a06 100644 --- a/drivers/net/benet/be_main.c +++ b/drivers/net/benet/be_main.c | |||
@@ -25,9 +25,9 @@ MODULE_DESCRIPTION(DRV_DESC " " DRV_VER); | |||
25 | MODULE_AUTHOR("ServerEngines Corporation"); | 25 | MODULE_AUTHOR("ServerEngines Corporation"); |
26 | MODULE_LICENSE("GPL"); | 26 | MODULE_LICENSE("GPL"); |
27 | 27 | ||
28 | static unsigned int rx_frag_size = 2048; | 28 | static ushort rx_frag_size = 2048; |
29 | static unsigned int num_vfs; | 29 | static unsigned int num_vfs; |
30 | module_param(rx_frag_size, uint, S_IRUGO); | 30 | module_param(rx_frag_size, ushort, S_IRUGO); |
31 | module_param(num_vfs, uint, S_IRUGO); | 31 | module_param(num_vfs, uint, S_IRUGO); |
32 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); | 32 | MODULE_PARM_DESC(rx_frag_size, "Size of a fragment that holds rcvd data."); |
33 | MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); | 33 | MODULE_PARM_DESC(num_vfs, "Number of PCI VFs to initialize"); |
@@ -851,31 +851,26 @@ static void be_rx_rate_update(struct be_rx_obj *rxo) | |||
851 | } | 851 | } |
852 | 852 | ||
853 | static void be_rx_stats_update(struct be_rx_obj *rxo, | 853 | static void be_rx_stats_update(struct be_rx_obj *rxo, |
854 | u32 pktsize, u16 numfrags, u8 pkt_type) | 854 | struct be_rx_compl_info *rxcp) |
855 | { | 855 | { |
856 | struct be_rx_stats *stats = &rxo->stats; | 856 | struct be_rx_stats *stats = &rxo->stats; |
857 | 857 | ||
858 | stats->rx_compl++; | 858 | stats->rx_compl++; |
859 | stats->rx_frags += numfrags; | 859 | stats->rx_frags += rxcp->num_rcvd; |
860 | stats->rx_bytes += pktsize; | 860 | stats->rx_bytes += rxcp->pkt_size; |
861 | stats->rx_pkts++; | 861 | stats->rx_pkts++; |
862 | if (pkt_type == BE_MULTICAST_PACKET) | 862 | if (rxcp->pkt_type == BE_MULTICAST_PACKET) |
863 | stats->rx_mcast_pkts++; | 863 | stats->rx_mcast_pkts++; |
864 | if (rxcp->err) | ||
865 | stats->rxcp_err++; | ||
864 | } | 866 | } |
865 | 867 | ||
866 | static inline bool csum_passed(struct be_eth_rx_compl *rxcp) | 868 | static inline bool csum_passed(struct be_rx_compl_info *rxcp) |
867 | { | 869 | { |
868 | u8 l4_cksm, ipv6, ipcksm, tcpf, udpf; | ||
869 | |||
870 | l4_cksm = AMAP_GET_BITS(struct amap_eth_rx_compl, l4_cksm, rxcp); | ||
871 | ipcksm = AMAP_GET_BITS(struct amap_eth_rx_compl, ipcksm, rxcp); | ||
872 | ipv6 = AMAP_GET_BITS(struct amap_eth_rx_compl, ip_version, rxcp); | ||
873 | tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); | ||
874 | udpf = AMAP_GET_BITS(struct amap_eth_rx_compl, udpf, rxcp); | ||
875 | |||
876 | /* L4 checksum is not reliable for non TCP/UDP packets. | 870 | /* L4 checksum is not reliable for non TCP/UDP packets. |
877 | * Also ignore ipcksm for ipv6 pkts */ | 871 | * Also ignore ipcksm for ipv6 pkts */ |
878 | return (tcpf || udpf) && l4_cksm && (ipcksm || ipv6); | 872 | return (rxcp->tcpf || rxcp->udpf) && rxcp->l4_csum && |
873 | (rxcp->ip_csum || rxcp->ipv6); | ||
879 | } | 874 | } |
880 | 875 | ||
881 | static struct be_rx_page_info * | 876 | static struct be_rx_page_info * |
@@ -903,20 +898,17 @@ get_rx_page_info(struct be_adapter *adapter, | |||
903 | /* Throwaway the data in the Rx completion */ | 898 | /* Throwaway the data in the Rx completion */ |
904 | static void be_rx_compl_discard(struct be_adapter *adapter, | 899 | static void be_rx_compl_discard(struct be_adapter *adapter, |
905 | struct be_rx_obj *rxo, | 900 | struct be_rx_obj *rxo, |
906 | struct be_eth_rx_compl *rxcp) | 901 | struct be_rx_compl_info *rxcp) |
907 | { | 902 | { |
908 | struct be_queue_info *rxq = &rxo->q; | 903 | struct be_queue_info *rxq = &rxo->q; |
909 | struct be_rx_page_info *page_info; | 904 | struct be_rx_page_info *page_info; |
910 | u16 rxq_idx, i, num_rcvd; | 905 | u16 i, num_rcvd = rxcp->num_rcvd; |
911 | |||
912 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | ||
913 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | ||
914 | 906 | ||
915 | for (i = 0; i < num_rcvd; i++) { | 907 | for (i = 0; i < num_rcvd; i++) { |
916 | page_info = get_rx_page_info(adapter, rxo, rxq_idx); | 908 | page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); |
917 | put_page(page_info->page); | 909 | put_page(page_info->page); |
918 | memset(page_info, 0, sizeof(*page_info)); | 910 | memset(page_info, 0, sizeof(*page_info)); |
919 | index_inc(&rxq_idx, rxq->len); | 911 | index_inc(&rxcp->rxq_idx, rxq->len); |
920 | } | 912 | } |
921 | } | 913 | } |
922 | 914 | ||
@@ -925,30 +917,23 @@ static void be_rx_compl_discard(struct be_adapter *adapter, | |||
925 | * indicated by rxcp. | 917 | * indicated by rxcp. |
926 | */ | 918 | */ |
927 | static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, | 919 | static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, |
928 | struct sk_buff *skb, struct be_eth_rx_compl *rxcp, | 920 | struct sk_buff *skb, struct be_rx_compl_info *rxcp) |
929 | u16 num_rcvd) | ||
930 | { | 921 | { |
931 | struct be_queue_info *rxq = &rxo->q; | 922 | struct be_queue_info *rxq = &rxo->q; |
932 | struct be_rx_page_info *page_info; | 923 | struct be_rx_page_info *page_info; |
933 | u16 rxq_idx, i, j; | 924 | u16 i, j; |
934 | u32 pktsize, hdr_len, curr_frag_len, size; | 925 | u16 hdr_len, curr_frag_len, remaining; |
935 | u8 *start; | 926 | u8 *start; |
936 | u8 pkt_type; | ||
937 | |||
938 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | ||
939 | pktsize = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); | ||
940 | pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); | ||
941 | |||
942 | page_info = get_rx_page_info(adapter, rxo, rxq_idx); | ||
943 | 927 | ||
928 | page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); | ||
944 | start = page_address(page_info->page) + page_info->page_offset; | 929 | start = page_address(page_info->page) + page_info->page_offset; |
945 | prefetch(start); | 930 | prefetch(start); |
946 | 931 | ||
947 | /* Copy data in the first descriptor of this completion */ | 932 | /* Copy data in the first descriptor of this completion */ |
948 | curr_frag_len = min(pktsize, rx_frag_size); | 933 | curr_frag_len = min(rxcp->pkt_size, rx_frag_size); |
949 | 934 | ||
950 | /* Copy the header portion into skb_data */ | 935 | /* Copy the header portion into skb_data */ |
951 | hdr_len = min((u32)BE_HDR_LEN, curr_frag_len); | 936 | hdr_len = min(BE_HDR_LEN, curr_frag_len); |
952 | memcpy(skb->data, start, hdr_len); | 937 | memcpy(skb->data, start, hdr_len); |
953 | skb->len = curr_frag_len; | 938 | skb->len = curr_frag_len; |
954 | if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */ | 939 | if (curr_frag_len <= BE_HDR_LEN) { /* tiny packet */ |
@@ -967,19 +952,17 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, | |||
967 | } | 952 | } |
968 | page_info->page = NULL; | 953 | page_info->page = NULL; |
969 | 954 | ||
970 | if (pktsize <= rx_frag_size) { | 955 | if (rxcp->pkt_size <= rx_frag_size) { |
971 | BUG_ON(num_rcvd != 1); | 956 | BUG_ON(rxcp->num_rcvd != 1); |
972 | goto done; | 957 | return; |
973 | } | 958 | } |
974 | 959 | ||
975 | /* More frags present for this completion */ | 960 | /* More frags present for this completion */ |
976 | size = pktsize; | 961 | index_inc(&rxcp->rxq_idx, rxq->len); |
977 | for (i = 1, j = 0; i < num_rcvd; i++) { | 962 | remaining = rxcp->pkt_size - curr_frag_len; |
978 | size -= curr_frag_len; | 963 | for (i = 1, j = 0; i < rxcp->num_rcvd; i++) { |
979 | index_inc(&rxq_idx, rxq->len); | 964 | page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); |
980 | page_info = get_rx_page_info(adapter, rxo, rxq_idx); | 965 | curr_frag_len = min(remaining, rx_frag_size); |
981 | |||
982 | curr_frag_len = min(size, rx_frag_size); | ||
983 | 966 | ||
984 | /* Coalesce all frags from the same physical page in one slot */ | 967 | /* Coalesce all frags from the same physical page in one slot */ |
985 | if (page_info->page_offset == 0) { | 968 | if (page_info->page_offset == 0) { |
@@ -998,25 +981,19 @@ static void skb_fill_rx_data(struct be_adapter *adapter, struct be_rx_obj *rxo, | |||
998 | skb->len += curr_frag_len; | 981 | skb->len += curr_frag_len; |
999 | skb->data_len += curr_frag_len; | 982 | skb->data_len += curr_frag_len; |
1000 | 983 | ||
984 | remaining -= curr_frag_len; | ||
985 | index_inc(&rxcp->rxq_idx, rxq->len); | ||
1001 | page_info->page = NULL; | 986 | page_info->page = NULL; |
1002 | } | 987 | } |
1003 | BUG_ON(j > MAX_SKB_FRAGS); | 988 | BUG_ON(j > MAX_SKB_FRAGS); |
1004 | |||
1005 | done: | ||
1006 | be_rx_stats_update(rxo, pktsize, num_rcvd, pkt_type); | ||
1007 | } | 989 | } |
1008 | 990 | ||
1009 | /* Process the RX completion indicated by rxcp when GRO is disabled */ | 991 | /* Process the RX completion indicated by rxcp when GRO is disabled */ |
1010 | static void be_rx_compl_process(struct be_adapter *adapter, | 992 | static void be_rx_compl_process(struct be_adapter *adapter, |
1011 | struct be_rx_obj *rxo, | 993 | struct be_rx_obj *rxo, |
1012 | struct be_eth_rx_compl *rxcp) | 994 | struct be_rx_compl_info *rxcp) |
1013 | { | 995 | { |
1014 | struct sk_buff *skb; | 996 | struct sk_buff *skb; |
1015 | u32 vlanf, vid; | ||
1016 | u16 num_rcvd; | ||
1017 | u8 vtm; | ||
1018 | |||
1019 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | ||
1020 | 997 | ||
1021 | skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); | 998 | skb = netdev_alloc_skb_ip_align(adapter->netdev, BE_HDR_LEN); |
1022 | if (unlikely(!skb)) { | 999 | if (unlikely(!skb)) { |
@@ -1026,7 +1003,7 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
1026 | return; | 1003 | return; |
1027 | } | 1004 | } |
1028 | 1005 | ||
1029 | skb_fill_rx_data(adapter, rxo, skb, rxcp, num_rcvd); | 1006 | skb_fill_rx_data(adapter, rxo, skb, rxcp); |
1030 | 1007 | ||
1031 | if (likely(adapter->rx_csum && csum_passed(rxcp))) | 1008 | if (likely(adapter->rx_csum && csum_passed(rxcp))) |
1032 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1009 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -1036,26 +1013,12 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
1036 | skb->truesize = skb->len + sizeof(struct sk_buff); | 1013 | skb->truesize = skb->len + sizeof(struct sk_buff); |
1037 | skb->protocol = eth_type_trans(skb, adapter->netdev); | 1014 | skb->protocol = eth_type_trans(skb, adapter->netdev); |
1038 | 1015 | ||
1039 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); | 1016 | if (unlikely(rxcp->vlanf)) { |
1040 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); | ||
1041 | |||
1042 | /* vlanf could be wrongly set in some cards. | ||
1043 | * ignore if vtm is not set */ | ||
1044 | if ((adapter->function_mode & 0x400) && !vtm) | ||
1045 | vlanf = 0; | ||
1046 | |||
1047 | if ((adapter->pvid == vlanf) && !adapter->vlan_tag[vlanf]) | ||
1048 | vlanf = 0; | ||
1049 | |||
1050 | if (unlikely(vlanf)) { | ||
1051 | if (!adapter->vlan_grp || adapter->vlans_added == 0) { | 1017 | if (!adapter->vlan_grp || adapter->vlans_added == 0) { |
1052 | kfree_skb(skb); | 1018 | kfree_skb(skb); |
1053 | return; | 1019 | return; |
1054 | } | 1020 | } |
1055 | vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); | 1021 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, rxcp->vid); |
1056 | if (!lancer_chip(adapter)) | ||
1057 | vid = swab16(vid); | ||
1058 | vlan_hwaccel_receive_skb(skb, adapter->vlan_grp, vid); | ||
1059 | } else { | 1022 | } else { |
1060 | netif_receive_skb(skb); | 1023 | netif_receive_skb(skb); |
1061 | } | 1024 | } |
@@ -1064,31 +1027,14 @@ static void be_rx_compl_process(struct be_adapter *adapter, | |||
1064 | /* Process the RX completion indicated by rxcp when GRO is enabled */ | 1027 | /* Process the RX completion indicated by rxcp when GRO is enabled */ |
1065 | static void be_rx_compl_process_gro(struct be_adapter *adapter, | 1028 | static void be_rx_compl_process_gro(struct be_adapter *adapter, |
1066 | struct be_rx_obj *rxo, | 1029 | struct be_rx_obj *rxo, |
1067 | struct be_eth_rx_compl *rxcp) | 1030 | struct be_rx_compl_info *rxcp) |
1068 | { | 1031 | { |
1069 | struct be_rx_page_info *page_info; | 1032 | struct be_rx_page_info *page_info; |
1070 | struct sk_buff *skb = NULL; | 1033 | struct sk_buff *skb = NULL; |
1071 | struct be_queue_info *rxq = &rxo->q; | 1034 | struct be_queue_info *rxq = &rxo->q; |
1072 | struct be_eq_obj *eq_obj = &rxo->rx_eq; | 1035 | struct be_eq_obj *eq_obj = &rxo->rx_eq; |
1073 | u32 num_rcvd, pkt_size, remaining, vlanf, curr_frag_len; | 1036 | u16 remaining, curr_frag_len; |
1074 | u16 i, rxq_idx = 0, vid, j; | 1037 | u16 i, j; |
1075 | u8 vtm; | ||
1076 | u8 pkt_type; | ||
1077 | |||
1078 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, rxcp); | ||
1079 | pkt_size = AMAP_GET_BITS(struct amap_eth_rx_compl, pktsize, rxcp); | ||
1080 | vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl, vtp, rxcp); | ||
1081 | rxq_idx = AMAP_GET_BITS(struct amap_eth_rx_compl, fragndx, rxcp); | ||
1082 | vtm = AMAP_GET_BITS(struct amap_eth_rx_compl, vtm, rxcp); | ||
1083 | pkt_type = AMAP_GET_BITS(struct amap_eth_rx_compl, cast_enc, rxcp); | ||
1084 | |||
1085 | /* vlanf could be wrongly set in some cards. | ||
1086 | * ignore if vtm is not set */ | ||
1087 | if ((adapter->function_mode & 0x400) && !vtm) | ||
1088 | vlanf = 0; | ||
1089 | |||
1090 | if ((adapter->pvid == vlanf) && !adapter->vlan_tag[vlanf]) | ||
1091 | vlanf = 0; | ||
1092 | 1038 | ||
1093 | skb = napi_get_frags(&eq_obj->napi); | 1039 | skb = napi_get_frags(&eq_obj->napi); |
1094 | if (!skb) { | 1040 | if (!skb) { |
@@ -1096,9 +1042,9 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1096 | return; | 1042 | return; |
1097 | } | 1043 | } |
1098 | 1044 | ||
1099 | remaining = pkt_size; | 1045 | remaining = rxcp->pkt_size; |
1100 | for (i = 0, j = -1; i < num_rcvd; i++) { | 1046 | for (i = 0, j = -1; i < rxcp->num_rcvd; i++) { |
1101 | page_info = get_rx_page_info(adapter, rxo, rxq_idx); | 1047 | page_info = get_rx_page_info(adapter, rxo, rxcp->rxq_idx); |
1102 | 1048 | ||
1103 | curr_frag_len = min(remaining, rx_frag_size); | 1049 | curr_frag_len = min(remaining, rx_frag_size); |
1104 | 1050 | ||
@@ -1116,56 +1062,109 @@ static void be_rx_compl_process_gro(struct be_adapter *adapter, | |||
1116 | skb_shinfo(skb)->frags[j].size += curr_frag_len; | 1062 | skb_shinfo(skb)->frags[j].size += curr_frag_len; |
1117 | 1063 | ||
1118 | remaining -= curr_frag_len; | 1064 | remaining -= curr_frag_len; |
1119 | index_inc(&rxq_idx, rxq->len); | 1065 | index_inc(&rxcp->rxq_idx, rxq->len); |
1120 | memset(page_info, 0, sizeof(*page_info)); | 1066 | memset(page_info, 0, sizeof(*page_info)); |
1121 | } | 1067 | } |
1122 | BUG_ON(j > MAX_SKB_FRAGS); | 1068 | BUG_ON(j > MAX_SKB_FRAGS); |
1123 | 1069 | ||
1124 | skb_shinfo(skb)->nr_frags = j + 1; | 1070 | skb_shinfo(skb)->nr_frags = j + 1; |
1125 | skb->len = pkt_size; | 1071 | skb->len = rxcp->pkt_size; |
1126 | skb->data_len = pkt_size; | 1072 | skb->data_len = rxcp->pkt_size; |
1127 | skb->truesize += pkt_size; | 1073 | skb->truesize += rxcp->pkt_size; |
1128 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1074 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
1129 | 1075 | ||
1130 | if (likely(!vlanf)) { | 1076 | if (likely(!rxcp->vlanf)) |
1131 | napi_gro_frags(&eq_obj->napi); | 1077 | napi_gro_frags(&eq_obj->napi); |
1132 | } else { | 1078 | else |
1133 | vid = AMAP_GET_BITS(struct amap_eth_rx_compl, vlan_tag, rxcp); | 1079 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, rxcp->vid); |
1134 | if (!lancer_chip(adapter)) | 1080 | } |
1135 | vid = swab16(vid); | 1081 | |
1082 | static void be_parse_rx_compl_v1(struct be_adapter *adapter, | ||
1083 | struct be_eth_rx_compl *compl, | ||
1084 | struct be_rx_compl_info *rxcp) | ||
1085 | { | ||
1086 | rxcp->pkt_size = | ||
1087 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, pktsize, compl); | ||
1088 | rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtp, compl); | ||
1089 | rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, err, compl); | ||
1090 | rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, tcpf, compl); | ||
1091 | rxcp->ip_csum = | ||
1092 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ipcksm, compl); | ||
1093 | rxcp->l4_csum = | ||
1094 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, l4_cksm, compl); | ||
1095 | rxcp->ipv6 = | ||
1096 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, ip_version, compl); | ||
1097 | rxcp->rxq_idx = | ||
1098 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, fragndx, compl); | ||
1099 | rxcp->num_rcvd = | ||
1100 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, numfrags, compl); | ||
1101 | rxcp->pkt_type = | ||
1102 | AMAP_GET_BITS(struct amap_eth_rx_compl_v1, cast_enc, compl); | ||
1103 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vtm, compl); | ||
1104 | rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v1, vlan_tag, compl); | ||
1105 | } | ||
1106 | |||
1107 | static void be_parse_rx_compl_v0(struct be_adapter *adapter, | ||
1108 | struct be_eth_rx_compl *compl, | ||
1109 | struct be_rx_compl_info *rxcp) | ||
1110 | { | ||
1111 | rxcp->pkt_size = | ||
1112 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, pktsize, compl); | ||
1113 | rxcp->vlanf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtp, compl); | ||
1114 | rxcp->err = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, err, compl); | ||
1115 | rxcp->tcpf = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, tcpf, compl); | ||
1116 | rxcp->ip_csum = | ||
1117 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ipcksm, compl); | ||
1118 | rxcp->l4_csum = | ||
1119 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, l4_cksm, compl); | ||
1120 | rxcp->ipv6 = | ||
1121 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, ip_version, compl); | ||
1122 | rxcp->rxq_idx = | ||
1123 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, fragndx, compl); | ||
1124 | rxcp->num_rcvd = | ||
1125 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, numfrags, compl); | ||
1126 | rxcp->pkt_type = | ||
1127 | AMAP_GET_BITS(struct amap_eth_rx_compl_v0, cast_enc, compl); | ||
1128 | rxcp->vtm = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vtm, compl); | ||
1129 | rxcp->vid = AMAP_GET_BITS(struct amap_eth_rx_compl_v0, vlan_tag, compl); | ||
1130 | } | ||
1131 | |||
1132 | static struct be_rx_compl_info *be_rx_compl_get(struct be_rx_obj *rxo) | ||
1133 | { | ||
1134 | struct be_eth_rx_compl *compl = queue_tail_node(&rxo->cq); | ||
1135 | struct be_rx_compl_info *rxcp = &rxo->rxcp; | ||
1136 | struct be_adapter *adapter = rxo->adapter; | ||
1136 | 1137 | ||
1137 | if (!adapter->vlan_grp || adapter->vlans_added == 0) | 1138 | /* For checking the valid bit it is Ok to use either definition as the |
1138 | return; | 1139 | * valid bit is at the same position in both v0 and v1 Rx compl */ |
1140 | if (compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] == 0) | ||
1141 | return NULL; | ||
1139 | 1142 | ||
1140 | vlan_gro_frags(&eq_obj->napi, adapter->vlan_grp, vid); | 1143 | rmb(); |
1141 | } | 1144 | be_dws_le_to_cpu(compl, sizeof(*compl)); |
1142 | 1145 | ||
1143 | be_rx_stats_update(rxo, pkt_size, num_rcvd, pkt_type); | 1146 | if (adapter->be3_native) |
1144 | } | 1147 | be_parse_rx_compl_v1(adapter, compl, rxcp); |
1148 | else | ||
1149 | be_parse_rx_compl_v0(adapter, compl, rxcp); | ||
1145 | 1150 | ||
1146 | static struct be_eth_rx_compl *be_rx_compl_get(struct be_rx_obj *rxo) | 1151 | /* vlanf could be wrongly set in some cards. ignore if vtm is not set */ |
1147 | { | 1152 | if ((adapter->function_mode & 0x400) && !rxcp->vtm) |
1148 | struct be_eth_rx_compl *rxcp = queue_tail_node(&rxo->cq); | 1153 | rxcp->vlanf = 0; |
1149 | 1154 | ||
1150 | if (rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] == 0) | 1155 | if (!lancer_chip(adapter)) |
1151 | return NULL; | 1156 | rxcp->vid = swab16(rxcp->vid); |
1152 | 1157 | ||
1153 | rmb(); | 1158 | if ((adapter->pvid == rxcp->vid) && !adapter->vlan_tag[rxcp->vid]) |
1154 | be_dws_le_to_cpu(rxcp, sizeof(*rxcp)); | 1159 | rxcp->vlanf = 0; |
1160 | |||
1161 | /* As the compl has been parsed, reset it; we wont touch it again */ | ||
1162 | compl->dw[offsetof(struct amap_eth_rx_compl_v1, valid) / 32] = 0; | ||
1155 | 1163 | ||
1156 | queue_tail_inc(&rxo->cq); | 1164 | queue_tail_inc(&rxo->cq); |
1157 | return rxcp; | 1165 | return rxcp; |
1158 | } | 1166 | } |
1159 | 1167 | ||
1160 | /* To reset the valid bit, we need to reset the whole word as | ||
1161 | * when walking the queue the valid entries are little-endian | ||
1162 | * and invalid entries are host endian | ||
1163 | */ | ||
1164 | static inline void be_rx_compl_reset(struct be_eth_rx_compl *rxcp) | ||
1165 | { | ||
1166 | rxcp->dw[offsetof(struct amap_eth_rx_compl, valid) / 32] = 0; | ||
1167 | } | ||
1168 | |||
1169 | static inline struct page *be_alloc_pages(u32 size, gfp_t gfp) | 1168 | static inline struct page *be_alloc_pages(u32 size, gfp_t gfp) |
1170 | { | 1169 | { |
1171 | u32 order = get_order(size); | 1170 | u32 order = get_order(size); |
@@ -1342,13 +1341,12 @@ static void be_rx_q_clean(struct be_adapter *adapter, struct be_rx_obj *rxo) | |||
1342 | struct be_rx_page_info *page_info; | 1341 | struct be_rx_page_info *page_info; |
1343 | struct be_queue_info *rxq = &rxo->q; | 1342 | struct be_queue_info *rxq = &rxo->q; |
1344 | struct be_queue_info *rx_cq = &rxo->cq; | 1343 | struct be_queue_info *rx_cq = &rxo->cq; |
1345 | struct be_eth_rx_compl *rxcp; | 1344 | struct be_rx_compl_info *rxcp; |
1346 | u16 tail; | 1345 | u16 tail; |
1347 | 1346 | ||
1348 | /* First cleanup pending rx completions */ | 1347 | /* First cleanup pending rx completions */ |
1349 | while ((rxcp = be_rx_compl_get(rxo)) != NULL) { | 1348 | while ((rxcp = be_rx_compl_get(rxo)) != NULL) { |
1350 | be_rx_compl_discard(adapter, rxo, rxcp); | 1349 | be_rx_compl_discard(adapter, rxo, rxcp); |
1351 | be_rx_compl_reset(rxcp); | ||
1352 | be_cq_notify(adapter, rx_cq->id, false, 1); | 1350 | be_cq_notify(adapter, rx_cq->id, false, 1); |
1353 | } | 1351 | } |
1354 | 1352 | ||
@@ -1697,15 +1695,9 @@ static irqreturn_t be_msix_tx_mcc(int irq, void *dev) | |||
1697 | return IRQ_HANDLED; | 1695 | return IRQ_HANDLED; |
1698 | } | 1696 | } |
1699 | 1697 | ||
1700 | static inline bool do_gro(struct be_rx_obj *rxo, | 1698 | static inline bool do_gro(struct be_rx_compl_info *rxcp) |
1701 | struct be_eth_rx_compl *rxcp, u8 err) | ||
1702 | { | 1699 | { |
1703 | int tcp_frame = AMAP_GET_BITS(struct amap_eth_rx_compl, tcpf, rxcp); | 1700 | return (rxcp->tcpf && !rxcp->err) ? true : false; |
1704 | |||
1705 | if (err) | ||
1706 | rxo->stats.rxcp_err++; | ||
1707 | |||
1708 | return (tcp_frame && !err) ? true : false; | ||
1709 | } | 1701 | } |
1710 | 1702 | ||
1711 | static int be_poll_rx(struct napi_struct *napi, int budget) | 1703 | static int be_poll_rx(struct napi_struct *napi, int budget) |
@@ -1714,10 +1706,8 @@ static int be_poll_rx(struct napi_struct *napi, int budget) | |||
1714 | struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq); | 1706 | struct be_rx_obj *rxo = container_of(rx_eq, struct be_rx_obj, rx_eq); |
1715 | struct be_adapter *adapter = rxo->adapter; | 1707 | struct be_adapter *adapter = rxo->adapter; |
1716 | struct be_queue_info *rx_cq = &rxo->cq; | 1708 | struct be_queue_info *rx_cq = &rxo->cq; |
1717 | struct be_eth_rx_compl *rxcp; | 1709 | struct be_rx_compl_info *rxcp; |
1718 | u32 work_done; | 1710 | u32 work_done; |
1719 | u16 num_rcvd; | ||
1720 | u8 err; | ||
1721 | 1711 | ||
1722 | rxo->stats.rx_polls++; | 1712 | rxo->stats.rx_polls++; |
1723 | for (work_done = 0; work_done < budget; work_done++) { | 1713 | for (work_done = 0; work_done < budget; work_done++) { |
@@ -1725,18 +1715,14 @@ static int be_poll_rx(struct napi_struct *napi, int budget) | |||
1725 | if (!rxcp) | 1715 | if (!rxcp) |
1726 | break; | 1716 | break; |
1727 | 1717 | ||
1728 | err = AMAP_GET_BITS(struct amap_eth_rx_compl, err, rxcp); | ||
1729 | num_rcvd = AMAP_GET_BITS(struct amap_eth_rx_compl, numfrags, | ||
1730 | rxcp); | ||
1731 | /* Ignore flush completions */ | 1718 | /* Ignore flush completions */ |
1732 | if (num_rcvd) { | 1719 | if (rxcp->num_rcvd) { |
1733 | if (do_gro(rxo, rxcp, err)) | 1720 | if (do_gro(rxcp)) |
1734 | be_rx_compl_process_gro(adapter, rxo, rxcp); | 1721 | be_rx_compl_process_gro(adapter, rxo, rxcp); |
1735 | else | 1722 | else |
1736 | be_rx_compl_process(adapter, rxo, rxcp); | 1723 | be_rx_compl_process(adapter, rxo, rxcp); |
1737 | } | 1724 | } |
1738 | 1725 | be_rx_stats_update(rxo, rxcp); | |
1739 | be_rx_compl_reset(rxcp); | ||
1740 | } | 1726 | } |
1741 | 1727 | ||
1742 | /* Refill the queue */ | 1728 | /* Refill the queue */ |
@@ -2868,6 +2854,7 @@ static int be_get_config(struct be_adapter *adapter) | |||
2868 | if (status) | 2854 | if (status) |
2869 | return status; | 2855 | return status; |
2870 | 2856 | ||
2857 | be_cmd_check_native_mode(adapter); | ||
2871 | return 0; | 2858 | return 0; |
2872 | } | 2859 | } |
2873 | 2860 | ||