diff options
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_mac.c')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_mac.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 1379c91a84a2..70707816db3d 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -903,16 +903,21 @@ static int fill_ctrlset(struct zd_mac *mac, | |||
903 | static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri) | 903 | static int zd_mac_tx(struct zd_mac *mac, struct ieee80211_txb *txb, int pri) |
904 | { | 904 | { |
905 | int i, r; | 905 | int i, r; |
906 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
906 | 907 | ||
907 | for (i = 0; i < txb->nr_frags; i++) { | 908 | for (i = 0; i < txb->nr_frags; i++) { |
908 | struct sk_buff *skb = txb->fragments[i]; | 909 | struct sk_buff *skb = txb->fragments[i]; |
909 | 910 | ||
910 | r = fill_ctrlset(mac, txb, i); | 911 | r = fill_ctrlset(mac, txb, i); |
911 | if (r) | 912 | if (r) { |
913 | ieee->stats.tx_dropped++; | ||
912 | return r; | 914 | return r; |
915 | } | ||
913 | r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len); | 916 | r = zd_usb_tx(&mac->chip.usb, skb->data, skb->len); |
914 | if (r) | 917 | if (r) { |
918 | ieee->stats.tx_dropped++; | ||
915 | return r; | 919 | return r; |
920 | } | ||
916 | } | 921 | } |
917 | 922 | ||
918 | /* FIXME: shouldn't this be handled by the upper layers? */ | 923 | /* FIXME: shouldn't this be handled by the upper layers? */ |
@@ -1062,9 +1067,23 @@ static int fill_rx_stats(struct ieee80211_rx_stats *stats, | |||
1062 | 1067 | ||
1063 | *pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status)); | 1068 | *pstatus = status = zd_tail(buffer, length, sizeof(struct rx_status)); |
1064 | if (status->frame_status & ZD_RX_ERROR) { | 1069 | if (status->frame_status & ZD_RX_ERROR) { |
1065 | /* FIXME: update? */ | 1070 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); |
1071 | ieee->stats.rx_errors++; | ||
1072 | if (status->frame_status & ZD_RX_TIMEOUT_ERROR) | ||
1073 | ieee->stats.rx_missed_errors++; | ||
1074 | else if (status->frame_status & ZD_RX_FIFO_OVERRUN_ERROR) | ||
1075 | ieee->stats.rx_fifo_errors++; | ||
1076 | else if (status->frame_status & ZD_RX_DECRYPTION_ERROR) | ||
1077 | ieee->ieee_stats.rx_discards_undecryptable++; | ||
1078 | else if (status->frame_status & ZD_RX_CRC32_ERROR) { | ||
1079 | ieee->stats.rx_crc_errors++; | ||
1080 | ieee->ieee_stats.rx_fcs_errors++; | ||
1081 | } | ||
1082 | else if (status->frame_status & ZD_RX_CRC16_ERROR) | ||
1083 | ieee->stats.rx_crc_errors++; | ||
1066 | return -EINVAL; | 1084 | return -EINVAL; |
1067 | } | 1085 | } |
1086 | |||
1068 | memset(stats, 0, sizeof(struct ieee80211_rx_stats)); | 1087 | memset(stats, 0, sizeof(struct ieee80211_rx_stats)); |
1069 | stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN + | 1088 | stats->len = length - (ZD_PLCP_HEADER_SIZE + IEEE80211_FCS_LEN + |
1070 | + sizeof(struct rx_status)); | 1089 | + sizeof(struct rx_status)); |
@@ -1093,6 +1112,8 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) | |||
1093 | if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + | 1112 | if (skb->len < ZD_PLCP_HEADER_SIZE + IEEE80211_1ADDR_LEN + |
1094 | IEEE80211_FCS_LEN + sizeof(struct rx_status)) | 1113 | IEEE80211_FCS_LEN + sizeof(struct rx_status)) |
1095 | { | 1114 | { |
1115 | ieee->stats.rx_errors++; | ||
1116 | ieee->stats.rx_length_errors++; | ||
1096 | dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n", | 1117 | dev_dbg_f(zd_mac_dev(mac), "Packet with length %u to small.\n", |
1097 | skb->len); | 1118 | skb->len); |
1098 | goto free_skb; | 1119 | goto free_skb; |
@@ -1100,7 +1121,9 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) | |||
1100 | 1121 | ||
1101 | r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); | 1122 | r = fill_rx_stats(&stats, &status, mac, skb->data, skb->len); |
1102 | if (r) { | 1123 | if (r) { |
1103 | /* Only packets with rx errors are included here. */ | 1124 | /* Only packets with rx errors are included here. |
1125 | * The error stats have already been set in fill_rx_stats. | ||
1126 | */ | ||
1104 | goto free_skb; | 1127 | goto free_skb; |
1105 | } | 1128 | } |
1106 | 1129 | ||
@@ -1113,8 +1136,10 @@ static void zd_mac_rx(struct zd_mac *mac, struct sk_buff *skb) | |||
1113 | 1136 | ||
1114 | r = filter_rx(ieee, skb->data, skb->len, &stats); | 1137 | r = filter_rx(ieee, skb->data, skb->len, &stats); |
1115 | if (r <= 0) { | 1138 | if (r <= 0) { |
1116 | if (r < 0) | 1139 | if (r < 0) { |
1140 | ieee->stats.rx_errors++; | ||
1117 | dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); | 1141 | dev_dbg_f(zd_mac_dev(mac), "Error in packet.\n"); |
1142 | } | ||
1118 | goto free_skb; | 1143 | goto free_skb; |
1119 | } | 1144 | } |
1120 | 1145 | ||
@@ -1145,7 +1170,9 @@ int zd_mac_rx_irq(struct zd_mac *mac, const u8 *buffer, unsigned int length) | |||
1145 | 1170 | ||
1146 | skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); | 1171 | skb = dev_alloc_skb(sizeof(struct zd_rt_hdr) + length); |
1147 | if (!skb) { | 1172 | if (!skb) { |
1173 | struct ieee80211_device *ieee = zd_mac_to_ieee80211(mac); | ||
1148 | dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); | 1174 | dev_warn(zd_mac_dev(mac), "Could not allocate skb.\n"); |
1175 | ieee->stats.rx_dropped++; | ||
1149 | return -ENOMEM; | 1176 | return -ENOMEM; |
1150 | } | 1177 | } |
1151 | skb_reserve(skb, sizeof(struct zd_rt_hdr)); | 1178 | skb_reserve(skb, sizeof(struct zd_rt_hdr)); |