Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

qeth: add layer 2 RX/TX checksum offloading

Checksum offloading for send and receive is already
supported for layer 3 (IP layer). This patch
adds support for RX and TX hardware checksum offloading
for layer 2 (MAC layer). The hardware calculates the checksum
for IP UDP and TCP packets.

This patch moves the hardware checksum offloading setup
to the set of common functions in qeth_core_main.c.
Layer 2 and layer 3 now simply call the same common functions.

Also note that TX checksum offloading is always enabled.
The device driver relies on the TCP/IP stack to make use of
this feature.

Signed-off-by: Thomas Richter <tmricht@linux.vnet.ibm.com>
Signed-off-by: Ursula Braun <ursula.braun@de.ibm.com>
Reviewed-by: Eugene Crosser <Eugene.Crosser@ru.ibm.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Thomas Richter and committed by
David S. Miller
4d7def2a 239ff408

+285 -147
+9
drivers/s390/net/qeth_core.h
··· 967 967 int qeth_query_ipassists(struct qeth_card *, enum qeth_prot_versions prot); 968 968 void qeth_trace_features(struct qeth_card *); 969 969 void qeth_close_dev(struct qeth_card *); 970 + int qeth_send_simple_setassparms(struct qeth_card *, enum qeth_ipa_funcs, 971 + __u16, long); 972 + int qeth_send_setassparms(struct qeth_card *, struct qeth_cmd_buffer *, __u16, 973 + long, 974 + int (*reply_cb)(struct qeth_card *, 975 + struct qeth_reply *, unsigned long), 976 + void *); 977 + int qeth_start_ipa_tx_checksum(struct qeth_card *); 978 + int qeth_set_rx_csum(struct qeth_card *, int); 970 979 971 980 /* exports for OSN */ 972 981 int qeth_osn_assist(struct net_device *, void *, int);
+171 -7
drivers/s390/net/qeth_core_main.c
··· 4978 4978 void qeth_trace_features(struct qeth_card *card) 4979 4979 { 4980 4980 QETH_CARD_TEXT(card, 2, "features"); 4981 - QETH_CARD_TEXT_(card, 2, "%x", card->options.ipa4.supported_funcs); 4982 - QETH_CARD_TEXT_(card, 2, "%x", card->options.ipa4.enabled_funcs); 4983 - QETH_CARD_TEXT_(card, 2, "%x", card->options.ipa6.supported_funcs); 4984 - QETH_CARD_TEXT_(card, 2, "%x", card->options.ipa6.enabled_funcs); 4985 - QETH_CARD_TEXT_(card, 2, "%x", card->options.adp.supported_funcs); 4986 - QETH_CARD_TEXT_(card, 2, "%x", card->options.adp.enabled_funcs); 4987 - QETH_CARD_TEXT_(card, 2, "%x", card->info.diagass_support); 4981 + QETH_CARD_HEX(card, 2, &card->options.ipa4, sizeof(card->options.ipa4)); 4982 + QETH_CARD_HEX(card, 2, &card->options.ipa6, sizeof(card->options.ipa6)); 4983 + QETH_CARD_HEX(card, 2, &card->options.adp, sizeof(card->options.adp)); 4984 + QETH_CARD_HEX(card, 2, &card->info.diagass_support, 4985 + sizeof(card->info.diagass_support)); 4988 4986 } 4989 4987 EXPORT_SYMBOL_GPL(qeth_trace_features); 4990 4988 ··· 5081 5083 } 5082 5084 5083 5085 card->options.ipa4.supported_funcs = 0; 5086 + card->options.ipa6.supported_funcs = 0; 5084 5087 card->options.adp.supported_funcs = 0; 5085 5088 card->options.sbp.supported_funcs = 0; 5086 5089 card->info.diagass_support = 0; ··· 5266 5267 return NULL; 5267 5268 } 5268 5269 EXPORT_SYMBOL_GPL(qeth_core_get_next_skb); 5270 + 5271 + static int qeth_setassparms_cb(struct qeth_card *card, 5272 + struct qeth_reply *reply, unsigned long data) 5273 + { 5274 + struct qeth_ipa_cmd *cmd; 5275 + 5276 + QETH_CARD_TEXT(card, 4, "defadpcb"); 5277 + 5278 + cmd = (struct qeth_ipa_cmd *) data; 5279 + if (cmd->hdr.return_code == 0) { 5280 + cmd->hdr.return_code = cmd->data.setassparms.hdr.return_code; 5281 + if (cmd->hdr.prot_version == QETH_PROT_IPV4) 5282 + card->options.ipa4.enabled_funcs = cmd->hdr.ipa_enabled; 5283 + if (cmd->hdr.prot_version == QETH_PROT_IPV6) 5284 + card->options.ipa6.enabled_funcs = cmd->hdr.ipa_enabled; 5285 + } 5286 + if (cmd->data.setassparms.hdr.assist_no == IPA_INBOUND_CHECKSUM && 5287 + cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) { 5288 + card->info.csum_mask = cmd->data.setassparms.data.flags_32bit; 5289 + QETH_CARD_TEXT_(card, 3, "csum:%d", card->info.csum_mask); 5290 + } 5291 + if (cmd->data.setassparms.hdr.assist_no == IPA_OUTBOUND_CHECKSUM && 5292 + cmd->data.setassparms.hdr.command_code == IPA_CMD_ASS_START) { 5293 + card->info.tx_csum_mask = 5294 + cmd->data.setassparms.data.flags_32bit; 5295 + QETH_CARD_TEXT_(card, 3, "tcsu:%d", card->info.tx_csum_mask); 5296 + } 5297 + 5298 + return 0; 5299 + } 5300 + 5301 + static struct qeth_cmd_buffer *qeth_get_setassparms_cmd(struct qeth_card *card, 5302 + enum qeth_ipa_funcs ipa_func, 5303 + __u16 cmd_code, __u16 len, 5304 + enum qeth_prot_versions prot) 5305 + { 5306 + struct qeth_cmd_buffer *iob; 5307 + struct qeth_ipa_cmd *cmd; 5308 + 5309 + QETH_CARD_TEXT(card, 4, "getasscm"); 5310 + iob = qeth_get_ipacmd_buffer(card, IPA_CMD_SETASSPARMS, prot); 5311 + 5312 + if (iob) { 5313 + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 5314 + cmd->data.setassparms.hdr.assist_no = ipa_func; 5315 + cmd->data.setassparms.hdr.length = 8 + len; 5316 + cmd->data.setassparms.hdr.command_code = cmd_code; 5317 + cmd->data.setassparms.hdr.return_code = 0; 5318 + cmd->data.setassparms.hdr.seq_no = 0; 5319 + } 5320 + 5321 + return iob; 5322 + } 5323 + 5324 + int qeth_send_setassparms(struct qeth_card *card, 5325 + struct qeth_cmd_buffer *iob, __u16 len, long data, 5326 + int (*reply_cb)(struct qeth_card *, 5327 + struct qeth_reply *, unsigned long), 5328 + void *reply_param) 5329 + { 5330 + int rc; 5331 + struct qeth_ipa_cmd *cmd; 5332 + 5333 + QETH_CARD_TEXT(card, 4, "sendassp"); 5334 + 5335 + cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 5336 + if (len <= sizeof(__u32)) 5337 + cmd->data.setassparms.data.flags_32bit = (__u32) data; 5338 + else /* (len > sizeof(__u32)) */ 5339 + memcpy(&cmd->data.setassparms.data, (void *) data, len); 5340 + 5341 + rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param); 5342 + return rc; 5343 + } 5344 + EXPORT_SYMBOL_GPL(qeth_send_setassparms); 5345 + 5346 + int qeth_send_simple_setassparms(struct qeth_card *card, 5347 + enum qeth_ipa_funcs ipa_func, 5348 + __u16 cmd_code, long data) 5349 + { 5350 + int rc; 5351 + int length = 0; 5352 + struct qeth_cmd_buffer *iob; 5353 + 5354 + QETH_CARD_TEXT(card, 4, "simassp4"); 5355 + if (data) 5356 + length = sizeof(__u32); 5357 + iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code, 5358 + length, QETH_PROT_IPV4); 5359 + if (!iob) 5360 + return -ENOMEM; 5361 + rc = qeth_send_setassparms(card, iob, length, data, 5362 + qeth_setassparms_cb, NULL); 5363 + return rc; 5364 + } 5365 + EXPORT_SYMBOL_GPL(qeth_send_simple_setassparms); 5269 5366 5270 5367 static void qeth_unregister_dbf_views(void) 5271 5368 { ··· 6048 5953 return 0; 6049 5954 } 6050 5955 EXPORT_SYMBOL_GPL(qeth_core_ethtool_get_settings); 5956 + 5957 + static int qeth_send_checksum_command(struct qeth_card *card) 5958 + { 5959 + int rc; 5960 + 5961 + rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM, 5962 + IPA_CMD_ASS_START, 0); 5963 + if (rc) { 5964 + dev_warn(&card->gdev->dev, "Starting HW checksumming for %s " 5965 + "failed, using SW checksumming\n", 5966 + QETH_CARD_IFNAME(card)); 5967 + return rc; 5968 + } 5969 + rc = qeth_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM, 5970 + IPA_CMD_ASS_ENABLE, 5971 + card->info.csum_mask); 5972 + if (rc) { 5973 + dev_warn(&card->gdev->dev, "Enabling HW checksumming for %s " 5974 + "failed, using SW checksumming\n", 5975 + QETH_CARD_IFNAME(card)); 5976 + return rc; 5977 + } 5978 + return 0; 5979 + } 5980 + 5981 + int qeth_set_rx_csum(struct qeth_card *card, int on) 5982 + { 5983 + int rc; 5984 + 5985 + if (on) { 5986 + rc = qeth_send_checksum_command(card); 5987 + if (rc) 5988 + return -EIO; 5989 + dev_info(&card->gdev->dev, 5990 + "HW Checksumming (inbound) enabled\n"); 5991 + } else { 5992 + rc = qeth_send_simple_setassparms(card, 5993 + IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0); 5994 + if (rc) 5995 + return -EIO; 5996 + } 5997 + return 0; 5998 + } 5999 + EXPORT_SYMBOL_GPL(qeth_set_rx_csum); 6000 + 6001 + int qeth_start_ipa_tx_checksum(struct qeth_card *card) 6002 + { 6003 + int rc = 0; 6004 + 6005 + if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) 6006 + return rc; 6007 + rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM, 6008 + IPA_CMD_ASS_START, 0); 6009 + if (rc) 6010 + goto err_out; 6011 + rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM, 6012 + IPA_CMD_ASS_ENABLE, 6013 + card->info.tx_csum_mask); 6014 + if (rc) 6015 + goto err_out; 6016 + 6017 + dev_info(&card->gdev->dev, "HW TX Checksumming enabled\n"); 6018 + return rc; 6019 + err_out: 6020 + dev_warn(&card->gdev->dev, "Enabling HW TX checksumming for %s " 6021 + "failed, using SW TX checksumming\n", QETH_CARD_IFNAME(card)); 6022 + return rc; 6023 + } 6024 + EXPORT_SYMBOL_GPL(qeth_start_ipa_tx_checksum); 6051 6025 6052 6026 static int __init qeth_core_init(void) 6053 6027 {
+80 -7
drivers/s390/net/qeth_l2_main.c
··· 252 252 return RTN_UNSPEC; 253 253 } 254 254 255 + static inline void qeth_l2_hdr_csum(struct qeth_card *card, 256 + struct qeth_hdr *hdr, struct sk_buff *skb) 257 + { 258 + struct iphdr *iph = ip_hdr(skb); 259 + 260 + /* tcph->check contains already the pseudo hdr checksum 261 + * so just set the header flags 262 + */ 263 + if (iph->protocol == IPPROTO_UDP) 264 + hdr->hdr.l2.flags[1] |= QETH_HDR_EXT_UDP; 265 + hdr->hdr.l2.flags[1] |= QETH_HDR_EXT_CSUM_TRANSP_REQ | 266 + QETH_HDR_EXT_CSUM_HDR_REQ; 267 + iph->check = 0; 268 + if (card->options.performance_stats) 269 + card->perf_stats.tx_csum++; 270 + } 271 + 255 272 static void qeth_l2_fill_header(struct qeth_card *card, struct qeth_hdr *hdr, 256 273 struct sk_buff *skb, int cast_type) 257 274 { ··· 407 390 return rc; 408 391 } 409 392 393 + static netdev_features_t qeth_l2_fix_features(struct net_device *dev, 394 + netdev_features_t features) 395 + { 396 + struct qeth_card *card = dev->ml_priv; 397 + 398 + QETH_DBF_TEXT(SETUP, 2, "fixfeat"); 399 + if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) 400 + features &= ~NETIF_F_IP_CSUM; 401 + if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) 402 + features &= ~NETIF_F_RXCSUM; 403 + QETH_DBF_HEX(SETUP, 2, &features, sizeof(features)); 404 + return features; 405 + } 406 + 407 + static int qeth_l2_set_features(struct net_device *dev, 408 + netdev_features_t features) 409 + { 410 + struct qeth_card *card = dev->ml_priv; 411 + netdev_features_t changed = dev->features ^ features; 412 + 413 + QETH_DBF_TEXT(SETUP, 2, "setfeat"); 414 + QETH_DBF_HEX(SETUP, 2, &features, sizeof(features)); 415 + 416 + if (card->state == CARD_STATE_DOWN || 417 + card->state == CARD_STATE_RECOVER) 418 + return 0; 419 + 420 + if (!(changed & NETIF_F_RXCSUM)) 421 + return 0; 422 + return qeth_set_rx_csum(card, features & NETIF_F_RXCSUM ? 1 : 0); 423 + } 424 + 410 425 static void qeth_l2_stop_card(struct qeth_card *card, int recovery_mode) 411 426 { 412 427 QETH_DBF_TEXT(SETUP , 2, "stopcard"); ··· 499 450 case QETH_HEADER_TYPE_LAYER2: 500 451 skb->pkt_type = PACKET_HOST; 501 452 skb->protocol = eth_type_trans(skb, skb->dev); 502 - skb->ip_summed = CHECKSUM_NONE; 453 + if ((card->dev->features & NETIF_F_RXCSUM) 454 + && ((hdr->hdr.l2.flags[1] & 455 + (QETH_HDR_EXT_CSUM_HDR_REQ | 456 + QETH_HDR_EXT_CSUM_TRANSP_REQ)) == 457 + (QETH_HDR_EXT_CSUM_HDR_REQ | 458 + QETH_HDR_EXT_CSUM_TRANSP_REQ))) 459 + skb->ip_summed = CHECKSUM_UNNECESSARY; 460 + else 461 + skb->ip_summed = CHECKSUM_NONE; 503 462 if (skb->protocol == htons(ETH_P_802_2)) 504 463 *((__u32 *)skb->cb) = ++card->seqno.pkt_seqno; 505 464 len = skb->len; ··· 860 803 sizeof(struct qeth_hdr)); 861 804 skb_set_mac_header(new_skb, sizeof(struct qeth_hdr)); 862 805 qeth_l2_fill_header(card, hdr, new_skb, cast_type); 806 + if (new_skb->ip_summed == CHECKSUM_PARTIAL) 807 + qeth_l2_hdr_csum(card, hdr, new_skb); 863 808 } 864 809 } 865 810 ··· 1027 968 .ndo_vlan_rx_add_vid = qeth_l2_vlan_rx_add_vid, 1028 969 .ndo_vlan_rx_kill_vid = qeth_l2_vlan_rx_kill_vid, 1029 970 .ndo_tx_timeout = qeth_tx_timeout, 971 + .ndo_fix_features = qeth_l2_fix_features, 972 + .ndo_set_features = qeth_l2_set_features 1030 973 }; 1031 974 1032 975 static int qeth_l2_setup_netdev(struct qeth_card *card) ··· 1058 997 (card->info.type != QETH_CARD_TYPE_OSN) ? 1059 998 &qeth_l2_ethtool_ops : &qeth_l2_osn_ops; 1060 999 card->dev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; 1000 + if (card->info.type == QETH_CARD_TYPE_OSD && !card->info.guestlan) { 1001 + card->dev->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM; 1002 + /* Turn on RX offloading per default */ 1003 + card->dev->features |= NETIF_F_RXCSUM; 1004 + } 1061 1005 card->info.broadcast_capable = 1; 1062 1006 qeth_l2_request_initial_mac(card); 1063 1007 SET_NETDEV_DEV(card->dev, &card->gdev->dev); 1064 1008 netif_napi_add(card->dev, &card->napi, qeth_l2_poll, QETH_NAPI_WEIGHT); 1065 1009 return register_netdev(card->dev); 1010 + } 1011 + 1012 + static int qeth_l2_start_ipassists(struct qeth_card *card) 1013 + { 1014 + /* configure isolation level */ 1015 + if (qeth_set_access_ctrl_online(card, 0)) 1016 + return -ENODEV; 1017 + if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) 1018 + qeth_set_rx_csum(card, 1); 1019 + qeth_start_ipa_tx_checksum(card); 1020 + return 0; 1066 1021 } 1067 1022 1068 1023 static int __qeth_l2_set_online(struct ccwgroup_device *gdev, int recovery_mode) ··· 1146 1069 contin: 1147 1070 if ((card->info.type == QETH_CARD_TYPE_OSD) || 1148 1071 (card->info.type == QETH_CARD_TYPE_OSX)) { 1149 - /* configure isolation level */ 1150 - rc = qeth_set_access_ctrl_online(card, 0); 1151 - if (rc) { 1152 - rc = -ENODEV; 1072 + if (qeth_l2_start_ipassists(card)) 1153 1073 goto out_remove; 1154 - } 1155 1074 } 1156 1075 1157 1076 if (card->info.type != QETH_CARD_TYPE_OSN && ··· 1526 1453 } 1527 1454 if (code & IPA_ADDR_CHANGE_CODE_MACADDR) { 1528 1455 snprintf(str[i], sizeof(str[i]), "MAC=%pM", 1529 - addr_lnid->mac); 1456 + addr_lnid->mac); 1530 1457 env[i] = str[i]; i++; 1531 1458 } 1532 1459 snprintf(str[i], sizeof(str[i]), "NTOK_BUSID=%x.%x.%04x",
+25 -133
drivers/s390/net/qeth_l3_main.c
··· 1065 1065 return iob; 1066 1066 } 1067 1067 1068 - static int qeth_l3_send_setassparms(struct qeth_card *card, 1069 - struct qeth_cmd_buffer *iob, __u16 len, long data, 1070 - int (*reply_cb)(struct qeth_card *, struct qeth_reply *, 1071 - unsigned long), 1072 - void *reply_param) 1073 - { 1074 - int rc; 1075 - struct qeth_ipa_cmd *cmd; 1076 - 1077 - QETH_CARD_TEXT(card, 4, "sendassp"); 1078 - 1079 - cmd = (struct qeth_ipa_cmd *)(iob->data+IPA_PDU_HEADER_SIZE); 1080 - if (len <= sizeof(__u32)) 1081 - cmd->data.setassparms.data.flags_32bit = (__u32) data; 1082 - else /* (len > sizeof(__u32)) */ 1083 - memcpy(&cmd->data.setassparms.data, (void *) data, len); 1084 - 1085 - rc = qeth_send_ipa_cmd(card, iob, reply_cb, reply_param); 1086 - return rc; 1087 - } 1088 - 1089 1068 #ifdef CONFIG_QETH_IPV6 1090 1069 static int qeth_l3_send_simple_setassparms_ipv6(struct qeth_card *card, 1091 1070 enum qeth_ipa_funcs ipa_func, __u16 cmd_code) ··· 1077 1098 0, QETH_PROT_IPV6); 1078 1099 if (!iob) 1079 1100 return -ENOMEM; 1080 - rc = qeth_l3_send_setassparms(card, iob, 0, 0, 1101 + rc = qeth_send_setassparms(card, iob, 0, 0, 1081 1102 qeth_l3_default_setassparms_cb, NULL); 1082 1103 return rc; 1083 1104 } 1084 1105 #endif 1085 - 1086 - static int qeth_l3_send_simple_setassparms(struct qeth_card *card, 1087 - enum qeth_ipa_funcs ipa_func, __u16 cmd_code, long data) 1088 - { 1089 - int rc; 1090 - int length = 0; 1091 - struct qeth_cmd_buffer *iob; 1092 - 1093 - QETH_CARD_TEXT(card, 4, "simassp4"); 1094 - if (data) 1095 - length = sizeof(__u32); 1096 - iob = qeth_l3_get_setassparms_cmd(card, ipa_func, cmd_code, 1097 - length, QETH_PROT_IPV4); 1098 - if (!iob) 1099 - return -ENOMEM; 1100 - rc = qeth_l3_send_setassparms(card, iob, length, data, 1101 - qeth_l3_default_setassparms_cb, NULL); 1102 - return rc; 1103 - } 1104 1106 1105 1107 static int qeth_l3_start_ipa_arp_processing(struct qeth_card *card) 1106 1108 { ··· 1095 1135 QETH_CARD_IFNAME(card)); 1096 1136 return 0; 1097 1137 } 1098 - rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, 1099 - IPA_CMD_ASS_START, 0); 1138 + rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING, 1139 + IPA_CMD_ASS_START, 0); 1100 1140 if (rc) { 1101 1141 dev_warn(&card->gdev->dev, 1102 1142 "Starting ARP processing support for %s failed\n", ··· 1118 1158 return -EOPNOTSUPP; 1119 1159 } 1120 1160 1121 - rc = qeth_l3_send_simple_setassparms(card, IPA_IP_FRAGMENTATION, 1161 + rc = qeth_send_simple_setassparms(card, IPA_IP_FRAGMENTATION, 1122 1162 IPA_CMD_ASS_START, 0); 1123 1163 if (rc) { 1124 1164 dev_warn(&card->gdev->dev, ··· 1143 1183 return -EOPNOTSUPP; 1144 1184 } 1145 1185 1146 - rc = qeth_l3_send_simple_setassparms(card, IPA_SOURCE_MAC, 1186 + rc = qeth_send_simple_setassparms(card, IPA_SOURCE_MAC, 1147 1187 IPA_CMD_ASS_START, 0); 1148 1188 if (rc) 1149 1189 dev_warn(&card->gdev->dev, ··· 1164 1204 return -EOPNOTSUPP; 1165 1205 } 1166 1206 1167 - rc = qeth_l3_send_simple_setassparms(card, IPA_VLAN_PRIO, 1207 + rc = qeth_send_simple_setassparms(card, IPA_VLAN_PRIO, 1168 1208 IPA_CMD_ASS_START, 0); 1169 1209 if (rc) { 1170 1210 dev_warn(&card->gdev->dev, ··· 1189 1229 return -EOPNOTSUPP; 1190 1230 } 1191 1231 1192 - rc = qeth_l3_send_simple_setassparms(card, IPA_MULTICASTING, 1232 + rc = qeth_send_simple_setassparms(card, IPA_MULTICASTING, 1193 1233 IPA_CMD_ASS_START, 0); 1194 1234 if (rc) { 1195 1235 dev_warn(&card->gdev->dev, ··· 1219 1259 QETH_CARD_IFNAME(card)); 1220 1260 return rc; 1221 1261 } 1222 - rc = qeth_l3_send_simple_setassparms(card, IPA_IPV6, 1262 + rc = qeth_send_simple_setassparms(card, IPA_IPV6, 1223 1263 IPA_CMD_ASS_START, 3); 1224 1264 if (rc) { 1225 1265 dev_err(&card->gdev->dev, ··· 1279 1319 rc = -EOPNOTSUPP; 1280 1320 goto out; 1281 1321 } 1282 - rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING, 1322 + rc = qeth_send_simple_setassparms(card, IPA_FILTERING, 1283 1323 IPA_CMD_ASS_START, 0); 1284 1324 if (rc) { 1285 1325 dev_warn(&card->gdev->dev, "Enabling broadcast filtering for " ··· 1287 1327 goto out; 1288 1328 } 1289 1329 1290 - rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING, 1330 + rc = qeth_send_simple_setassparms(card, IPA_FILTERING, 1291 1331 IPA_CMD_ASS_CONFIGURE, 1); 1292 1332 if (rc) { 1293 1333 dev_warn(&card->gdev->dev, ··· 1297 1337 } 1298 1338 card->info.broadcast_capable = QETH_BROADCAST_WITH_ECHO; 1299 1339 dev_info(&card->gdev->dev, "Broadcast enabled\n"); 1300 - rc = qeth_l3_send_simple_setassparms(card, IPA_FILTERING, 1340 + rc = qeth_send_simple_setassparms(card, IPA_FILTERING, 1301 1341 IPA_CMD_ASS_ENABLE, 1); 1302 1342 if (rc) { 1303 1343 dev_warn(&card->gdev->dev, "Setting up broadcast echo " ··· 1313 1353 return rc; 1314 1354 } 1315 1355 1316 - static int qeth_l3_send_checksum_command(struct qeth_card *card) 1317 - { 1318 - int rc; 1319 - 1320 - rc = qeth_l3_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM, 1321 - IPA_CMD_ASS_START, 0); 1322 - if (rc) { 1323 - dev_warn(&card->gdev->dev, "Starting HW checksumming for %s " 1324 - "failed, using SW checksumming\n", 1325 - QETH_CARD_IFNAME(card)); 1326 - return rc; 1327 - } 1328 - rc = qeth_l3_send_simple_setassparms(card, IPA_INBOUND_CHECKSUM, 1329 - IPA_CMD_ASS_ENABLE, 1330 - card->info.csum_mask); 1331 - if (rc) { 1332 - dev_warn(&card->gdev->dev, "Enabling HW checksumming for %s " 1333 - "failed, using SW checksumming\n", 1334 - QETH_CARD_IFNAME(card)); 1335 - return rc; 1336 - } 1337 - return 0; 1338 - } 1339 - 1340 - static int qeth_l3_set_rx_csum(struct qeth_card *card, int on) 1341 - { 1342 - int rc = 0; 1343 - 1344 - if (on) { 1345 - rc = qeth_l3_send_checksum_command(card); 1346 - if (rc) 1347 - return -EIO; 1348 - dev_info(&card->gdev->dev, 1349 - "HW Checksumming (inbound) enabled\n"); 1350 - } else { 1351 - rc = qeth_l3_send_simple_setassparms(card, 1352 - IPA_INBOUND_CHECKSUM, IPA_CMD_ASS_STOP, 0); 1353 - if (rc) 1354 - return -EIO; 1355 - } 1356 - 1357 - return 0; 1358 - } 1359 - 1360 - static int qeth_l3_start_ipa_checksum(struct qeth_card *card) 1356 + static void qeth_l3_start_ipa_checksum(struct qeth_card *card) 1361 1357 { 1362 1358 QETH_CARD_TEXT(card, 3, "strtcsum"); 1363 - 1364 - if (card->dev->features & NETIF_F_RXCSUM) { 1365 - rtnl_lock(); 1366 - /* force set_features call */ 1367 - card->dev->features &= ~NETIF_F_RXCSUM; 1368 - netdev_update_features(card->dev); 1369 - rtnl_unlock(); 1370 - } 1371 - return 0; 1359 + if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM) 1360 + && (card->dev->features & NETIF_F_RXCSUM)) 1361 + qeth_set_rx_csum(card, 1); 1372 1362 } 1373 1363 1374 - static int qeth_l3_start_ipa_tx_checksum(struct qeth_card *card) 1364 + static void qeth_l3_start_ipa_tx_checksum(struct qeth_card *card) 1375 1365 { 1376 - int rc = 0; 1377 - 1378 - if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM)) 1379 - return rc; 1380 - rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM, 1381 - IPA_CMD_ASS_START, 0); 1382 - if (rc) 1383 - goto err_out; 1384 - rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_CHECKSUM, 1385 - IPA_CMD_ASS_ENABLE, card->info.tx_csum_mask); 1386 - if (rc) 1387 - goto err_out; 1388 - dev_info(&card->gdev->dev, "HW TX Checksumming enabled\n"); 1389 - return rc; 1390 - err_out: 1391 - dev_warn(&card->gdev->dev, "Enabling HW TX checksumming for %s " 1392 - "failed, using SW TX checksumming\n", QETH_CARD_IFNAME(card)); 1393 - return rc; 1366 + QETH_CARD_TEXT(card, 3, "strttxcs"); 1367 + qeth_start_ipa_tx_checksum(card); 1394 1368 } 1395 1369 1396 1370 static int qeth_l3_start_ipa_tso(struct qeth_card *card) ··· 1339 1445 QETH_CARD_IFNAME(card)); 1340 1446 rc = -EOPNOTSUPP; 1341 1447 } else { 1342 - rc = qeth_l3_send_simple_setassparms(card, IPA_OUTBOUND_TSO, 1343 - IPA_CMD_ASS_START, 0); 1448 + rc = qeth_send_simple_setassparms(card, IPA_OUTBOUND_TSO, 1449 + IPA_CMD_ASS_START, 0); 1344 1450 if (rc) 1345 1451 dev_warn(&card->gdev->dev, "Starting outbound TCP " 1346 1452 "segmentation offload for %s failed\n", ··· 1844 1950 skb->ip_summed = CHECKSUM_NONE; 1845 1951 } else 1846 1952 skb->ip_summed = CHECKSUM_NONE; 1847 - 1848 1953 return is_vlan; 1849 1954 } 1850 1955 ··· 2180 2287 if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { 2181 2288 return -EOPNOTSUPP; 2182 2289 } 2183 - rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, 2290 + rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING, 2184 2291 IPA_CMD_ASS_ARP_SET_NO_ENTRIES, 2185 2292 no_entries); 2186 2293 if (rc) { ··· 2445 2552 QETH_PROT_IPV4); 2446 2553 if (!iob) 2447 2554 return -ENOMEM; 2448 - rc = qeth_l3_send_setassparms(card, iob, 2555 + rc = qeth_send_setassparms(card, iob, 2449 2556 sizeof(struct qeth_arp_cache_entry), 2450 2557 (unsigned long) entry, 2451 2558 qeth_l3_default_setassparms_cb, NULL); ··· 2486 2593 QETH_PROT_IPV4); 2487 2594 if (!iob) 2488 2595 return -ENOMEM; 2489 - rc = qeth_l3_send_setassparms(card, iob, 2596 + rc = qeth_send_setassparms(card, iob, 2490 2597 12, (unsigned long)buf, 2491 2598 qeth_l3_default_setassparms_cb, NULL); 2492 2599 if (rc) { ··· 2517 2624 if (!qeth_is_supported(card, IPA_ARP_PROCESSING)) { 2518 2625 return -EOPNOTSUPP; 2519 2626 } 2520 - rc = qeth_l3_send_simple_setassparms(card, IPA_ARP_PROCESSING, 2627 + rc = qeth_send_simple_setassparms(card, IPA_ARP_PROCESSING, 2521 2628 IPA_CMD_ASS_ARP_FLUSH_CACHE, 0); 2522 2629 if (rc) { 2523 2630 tmp = rc; ··· 3080 3187 features &= ~NETIF_F_TSO; 3081 3188 if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM)) 3082 3189 features &= ~NETIF_F_RXCSUM; 3083 - 3084 3190 return features; 3085 3191 } 3086 3192 ··· 3096 3204 card->state == CARD_STATE_RECOVER) 3097 3205 return 0; 3098 3206 3099 - return qeth_l3_set_rx_csum(card, features & NETIF_F_RXCSUM ? 1 : 0); 3207 + return qeth_set_rx_csum(card, features & NETIF_F_RXCSUM ? 1 : 0); 3100 3208 } 3101 3209 3102 3210 static const struct ethtool_ops qeth_l3_ethtool_ops = {