aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sfc/falcon.c
diff options
context:
space:
mode:
authorBen Hutchings <bhutchings@solarflare.com>2008-09-01 07:46:03 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-09-03 09:53:43 -0400
commit5b39fe307b58fc6d71265eeed809ab799a2e2ec9 (patch)
tree6f6c383237a1b4b297cd00613c225d9d8de8d9df /drivers/net/sfc/falcon.c
parent11f34e691d6b3501606a9eaf5379ec718d2fabeb (diff)
sfc: Remove mistaken hardware workaround
We believed that some valid SNAP frames were being marked as invalid. In fact this is not the case and no workaround is needed. Signed-off-by: Ben Hutchings <bhutchings@solarflare.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/net/sfc/falcon.c')
-rw-r--r--drivers/net/sfc/falcon.c65
1 files changed, 4 insertions, 61 deletions
diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c
index b73f1ea8bd58..f5753222133e 100644
--- a/drivers/net/sfc/falcon.c
+++ b/drivers/net/sfc/falcon.c
@@ -848,31 +848,11 @@ static inline void falcon_handle_tx_event(struct efx_channel *channel,
848 } 848 }
849} 849}
850 850
851/* Check received packet's destination MAC address. */
852static int check_dest_mac(struct efx_rx_queue *rx_queue,
853 const efx_qword_t *event)
854{
855 struct efx_rx_buffer *rx_buf;
856 struct efx_nic *efx = rx_queue->efx;
857 int rx_ev_desc_ptr;
858 struct ethhdr *eh;
859
860 if (efx->promiscuous)
861 return 1;
862
863 rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, RX_EV_DESC_PTR);
864 rx_buf = efx_rx_buffer(rx_queue, rx_ev_desc_ptr);
865 eh = (struct ethhdr *)rx_buf->data;
866 if (memcmp(eh->h_dest, efx->net_dev->dev_addr, ETH_ALEN))
867 return 0;
868 return 1;
869}
870
871/* Detect errors included in the rx_evt_pkt_ok bit. */ 851/* Detect errors included in the rx_evt_pkt_ok bit. */
872static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue, 852static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
873 const efx_qword_t *event, 853 const efx_qword_t *event,
874 unsigned *rx_ev_pkt_ok, 854 unsigned *rx_ev_pkt_ok,
875 int *discard, int byte_count) 855 int *discard)
876{ 856{
877 struct efx_nic *efx = rx_queue->efx; 857 struct efx_nic *efx = rx_queue->efx;
878 unsigned rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err; 858 unsigned rx_ev_buf_owner_id_err, rx_ev_ip_hdr_chksum_err;
@@ -880,7 +860,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
880 unsigned rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc; 860 unsigned rx_ev_frm_trunc, rx_ev_drib_nib, rx_ev_tobe_disc;
881 unsigned rx_ev_pkt_type, rx_ev_other_err, rx_ev_pause_frm; 861 unsigned rx_ev_pkt_type, rx_ev_other_err, rx_ev_pause_frm;
882 unsigned rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt; 862 unsigned rx_ev_ip_frag_err, rx_ev_hdr_type, rx_ev_mcast_pkt;
883 int snap, non_ip;
884 863
885 rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE); 864 rx_ev_hdr_type = EFX_QWORD_FIELD(*event, RX_EV_HDR_TYPE);
886 rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, RX_EV_MCAST_PKT); 865 rx_ev_mcast_pkt = EFX_QWORD_FIELD(*event, RX_EV_MCAST_PKT);
@@ -904,41 +883,6 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
904 rx_ev_buf_owner_id_err | rx_ev_eth_crc_err | 883 rx_ev_buf_owner_id_err | rx_ev_eth_crc_err |
905 rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err); 884 rx_ev_frm_trunc | rx_ev_ip_hdr_chksum_err);
906 885
907 snap = (rx_ev_pkt_type == RX_EV_PKT_TYPE_LLC_DECODE) ||
908 (rx_ev_pkt_type == RX_EV_PKT_TYPE_VLAN_LLC_DECODE);
909 non_ip = (rx_ev_hdr_type == RX_EV_HDR_TYPE_NON_IP_DECODE);
910
911 /* SFC bug 5475/8970: The Falcon XMAC incorrectly calculates the
912 * length field of an LLC frame, which sets TOBE_DISC. We could set
913 * PASS_LEN_ERR, but we want the MAC to filter out short frames (to
914 * protect the RX block).
915 *
916 * bug5475 - LLC/SNAP: Falcon identifies SNAP packets.
917 * bug8970 - LLC/noSNAP: Falcon does not provide an LLC flag.
918 * LLC can't encapsulate IP, so by definition
919 * these packets are NON_IP.
920 *
921 * Unicast mismatch will also cause TOBE_DISC, so the driver needs
922 * to check this.
923 */
924 if (EFX_WORKAROUND_5475(efx) && rx_ev_tobe_disc && (snap || non_ip)) {
925 /* If all the other flags are zero then we can state the
926 * entire packet is ok, which will flag to the kernel not
927 * to recalculate checksums.
928 */
929 if (!(non_ip | rx_ev_other_err | rx_ev_pause_frm))
930 *rx_ev_pkt_ok = 1;
931
932 rx_ev_tobe_disc = 0;
933
934 /* TOBE_DISC is set for unicast mismatch. But given that
935 * we can't trust TOBE_DISC here, we must validate the dest
936 * MAC address ourselves.
937 */
938 if (!rx_ev_mcast_pkt && !check_dest_mac(rx_queue, event))
939 rx_ev_tobe_disc = 1;
940 }
941
942 /* Count errors that are not in MAC stats. */ 886 /* Count errors that are not in MAC stats. */
943 if (rx_ev_frm_trunc) 887 if (rx_ev_frm_trunc)
944 ++rx_queue->channel->n_rx_frm_trunc; 888 ++rx_queue->channel->n_rx_frm_trunc;
@@ -962,7 +906,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
962#ifdef EFX_ENABLE_DEBUG 906#ifdef EFX_ENABLE_DEBUG
963 if (rx_ev_other_err) { 907 if (rx_ev_other_err) {
964 EFX_INFO_RL(efx, " RX queue %d unexpected RX event " 908 EFX_INFO_RL(efx, " RX queue %d unexpected RX event "
965 EFX_QWORD_FMT "%s%s%s%s%s%s%s%s%s\n", 909 EFX_QWORD_FMT "%s%s%s%s%s%s%s%s\n",
966 rx_queue->queue, EFX_QWORD_VAL(*event), 910 rx_queue->queue, EFX_QWORD_VAL(*event),
967 rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "", 911 rx_ev_buf_owner_id_err ? " [OWNER_ID_ERR]" : "",
968 rx_ev_ip_hdr_chksum_err ? 912 rx_ev_ip_hdr_chksum_err ?
@@ -973,8 +917,7 @@ static void falcon_handle_rx_not_ok(struct efx_rx_queue *rx_queue,
973 rx_ev_frm_trunc ? " [FRM_TRUNC]" : "", 917 rx_ev_frm_trunc ? " [FRM_TRUNC]" : "",
974 rx_ev_drib_nib ? " [DRIB_NIB]" : "", 918 rx_ev_drib_nib ? " [DRIB_NIB]" : "",
975 rx_ev_tobe_disc ? " [TOBE_DISC]" : "", 919 rx_ev_tobe_disc ? " [TOBE_DISC]" : "",
976 rx_ev_pause_frm ? " [PAUSE]" : "", 920 rx_ev_pause_frm ? " [PAUSE]" : "");
977 snap ? " [SNAP/LLC]" : "");
978 } 921 }
979#endif 922#endif
980 923
@@ -1041,7 +984,7 @@ static inline int falcon_handle_rx_event(struct efx_channel *channel,
1041 checksummed = RX_EV_HDR_TYPE_HAS_CHECKSUMS(rx_ev_hdr_type); 984 checksummed = RX_EV_HDR_TYPE_HAS_CHECKSUMS(rx_ev_hdr_type);
1042 } else { 985 } else {
1043 falcon_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok, 986 falcon_handle_rx_not_ok(rx_queue, event, &rx_ev_pkt_ok,
1044 &discard, rx_ev_byte_cnt); 987 &discard);
1045 checksummed = 0; 988 checksummed = 0;
1046 } 989 }
1047 990