|
@@ -1467,13 +1467,13 @@ static int qeth_setup_card(struct qeth_card *card)
|
|
card->lan_online = 0;
|
|
card->lan_online = 0;
|
|
card->read_or_write_problem = 0;
|
|
card->read_or_write_problem = 0;
|
|
card->dev = NULL;
|
|
card->dev = NULL;
|
|
- spin_lock_init(&card->vlanlock);
|
|
|
|
spin_lock_init(&card->mclock);
|
|
spin_lock_init(&card->mclock);
|
|
spin_lock_init(&card->lock);
|
|
spin_lock_init(&card->lock);
|
|
spin_lock_init(&card->ip_lock);
|
|
spin_lock_init(&card->ip_lock);
|
|
spin_lock_init(&card->thread_mask_lock);
|
|
spin_lock_init(&card->thread_mask_lock);
|
|
mutex_init(&card->conf_mutex);
|
|
mutex_init(&card->conf_mutex);
|
|
mutex_init(&card->discipline_mutex);
|
|
mutex_init(&card->discipline_mutex);
|
|
|
|
+ mutex_init(&card->vid_list_mutex);
|
|
card->thread_start_mask = 0;
|
|
card->thread_start_mask = 0;
|
|
card->thread_allowed_mask = 0;
|
|
card->thread_allowed_mask = 0;
|
|
card->thread_running_mask = 0;
|
|
card->thread_running_mask = 0;
|
|
@@ -3588,15 +3588,14 @@ static void qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
|
|
|
|
- unsigned long card_ptr)
|
|
|
|
|
|
+static void qeth_qdio_start_poll(struct ccw_device *ccwdev, int queue,
|
|
|
|
+ unsigned long card_ptr)
|
|
{
|
|
{
|
|
struct qeth_card *card = (struct qeth_card *)card_ptr;
|
|
struct qeth_card *card = (struct qeth_card *)card_ptr;
|
|
|
|
|
|
if (card->dev && (card->dev->flags & IFF_UP))
|
|
if (card->dev && (card->dev->flags & IFF_UP))
|
|
napi_schedule(&card->napi);
|
|
napi_schedule(&card->napi);
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL_GPL(qeth_qdio_start_poll);
|
|
|
|
|
|
|
|
int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq)
|
|
int qeth_configure_cq(struct qeth_card *card, enum qeth_cq cq)
|
|
{
|
|
{
|
|
@@ -3698,9 +3697,10 @@ out:
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
-void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
|
|
|
|
- unsigned int queue, int first_elem, int count,
|
|
|
|
- unsigned long card_ptr)
|
|
|
|
|
|
+static void qeth_qdio_input_handler(struct ccw_device *ccwdev,
|
|
|
|
+ unsigned int qdio_err, int queue,
|
|
|
|
+ int first_elem, int count,
|
|
|
|
+ unsigned long card_ptr)
|
|
{
|
|
{
|
|
struct qeth_card *card = (struct qeth_card *)card_ptr;
|
|
struct qeth_card *card = (struct qeth_card *)card_ptr;
|
|
|
|
|
|
@@ -3711,14 +3711,12 @@ void qeth_qdio_input_handler(struct ccw_device *ccwdev, unsigned int qdio_err,
|
|
qeth_qdio_cq_handler(card, qdio_err, queue, first_elem, count);
|
|
qeth_qdio_cq_handler(card, qdio_err, queue, first_elem, count);
|
|
else if (qdio_err)
|
|
else if (qdio_err)
|
|
qeth_schedule_recovery(card);
|
|
qeth_schedule_recovery(card);
|
|
-
|
|
|
|
-
|
|
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL_GPL(qeth_qdio_input_handler);
|
|
|
|
|
|
|
|
-void qeth_qdio_output_handler(struct ccw_device *ccwdev,
|
|
|
|
- unsigned int qdio_error, int __queue, int first_element,
|
|
|
|
- int count, unsigned long card_ptr)
|
|
|
|
|
|
+static void qeth_qdio_output_handler(struct ccw_device *ccwdev,
|
|
|
|
+ unsigned int qdio_error, int __queue,
|
|
|
|
+ int first_element, int count,
|
|
|
|
+ unsigned long card_ptr)
|
|
{
|
|
{
|
|
struct qeth_card *card = (struct qeth_card *) card_ptr;
|
|
struct qeth_card *card = (struct qeth_card *) card_ptr;
|
|
struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
|
|
struct qeth_qdio_out_q *queue = card->qdio.out_qs[__queue];
|
|
@@ -3787,7 +3785,6 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
|
|
card->perf_stats.outbound_handler_time += qeth_get_micros() -
|
|
card->perf_stats.outbound_handler_time += qeth_get_micros() -
|
|
card->perf_stats.outbound_handler_start_time;
|
|
card->perf_stats.outbound_handler_start_time;
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL_GPL(qeth_qdio_output_handler);
|
|
|
|
|
|
|
|
/* We cannot use outbound queue 3 for unicast packets on HiperSockets */
|
|
/* We cannot use outbound queue 3 for unicast packets on HiperSockets */
|
|
static inline int qeth_cut_iqd_prio(struct qeth_card *card, int queue_num)
|
|
static inline int qeth_cut_iqd_prio(struct qeth_card *card, int queue_num)
|
|
@@ -4995,7 +4992,7 @@ static int qeth_qdio_establish(struct qeth_card *card)
|
|
goto out_free_in_sbals;
|
|
goto out_free_in_sbals;
|
|
}
|
|
}
|
|
for (i = 0; i < card->qdio.no_in_queues; ++i)
|
|
for (i = 0; i < card->qdio.no_in_queues; ++i)
|
|
- queue_start_poll[i] = card->discipline->start_poll;
|
|
|
|
|
|
+ queue_start_poll[i] = qeth_qdio_start_poll;
|
|
|
|
|
|
qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll);
|
|
qeth_qdio_establish_cq(card, in_sbal_ptrs, queue_start_poll);
|
|
|
|
|
|
@@ -5019,8 +5016,8 @@ static int qeth_qdio_establish(struct qeth_card *card)
|
|
init_data.qib_param_field = qib_param_field;
|
|
init_data.qib_param_field = qib_param_field;
|
|
init_data.no_input_qs = card->qdio.no_in_queues;
|
|
init_data.no_input_qs = card->qdio.no_in_queues;
|
|
init_data.no_output_qs = card->qdio.no_out_queues;
|
|
init_data.no_output_qs = card->qdio.no_out_queues;
|
|
- init_data.input_handler = card->discipline->input_handler;
|
|
|
|
- init_data.output_handler = card->discipline->output_handler;
|
|
|
|
|
|
+ init_data.input_handler = qeth_qdio_input_handler;
|
|
|
|
+ init_data.output_handler = qeth_qdio_output_handler;
|
|
init_data.queue_start_poll_array = queue_start_poll;
|
|
init_data.queue_start_poll_array = queue_start_poll;
|
|
init_data.int_parm = (unsigned long) card;
|
|
init_data.int_parm = (unsigned long) card;
|
|
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
|
|
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
|
|
@@ -5204,6 +5201,11 @@ retriable:
|
|
rc = qeth_query_ipassists(card, QETH_PROT_IPV4);
|
|
rc = qeth_query_ipassists(card, QETH_PROT_IPV4);
|
|
if (rc == -ENOMEM)
|
|
if (rc == -ENOMEM)
|
|
goto out;
|
|
goto out;
|
|
|
|
+ if (qeth_is_supported(card, IPA_IPV6)) {
|
|
|
|
+ rc = qeth_query_ipassists(card, QETH_PROT_IPV6);
|
|
|
|
+ if (rc == -ENOMEM)
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
|
|
if (qeth_is_supported(card, IPA_SETADAPTERPARMS)) {
|
|
rc = qeth_query_setadapterparms(card);
|
|
rc = qeth_query_setadapterparms(card);
|
|
if (rc < 0) {
|
|
if (rc < 0) {
|
|
@@ -5511,26 +5513,26 @@ int qeth_send_setassparms(struct qeth_card *card,
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(qeth_send_setassparms);
|
|
EXPORT_SYMBOL_GPL(qeth_send_setassparms);
|
|
|
|
|
|
-int qeth_send_simple_setassparms(struct qeth_card *card,
|
|
|
|
- enum qeth_ipa_funcs ipa_func,
|
|
|
|
- __u16 cmd_code, long data)
|
|
|
|
|
|
+int qeth_send_simple_setassparms_prot(struct qeth_card *card,
|
|
|
|
+ enum qeth_ipa_funcs ipa_func,
|
|
|
|
+ u16 cmd_code, long data,
|
|
|
|
+ enum qeth_prot_versions prot)
|
|
{
|
|
{
|
|
int rc;
|
|
int rc;
|
|
int length = 0;
|
|
int length = 0;
|
|
struct qeth_cmd_buffer *iob;
|
|
struct qeth_cmd_buffer *iob;
|
|
|
|
|
|
- QETH_CARD_TEXT(card, 4, "simassp4");
|
|
|
|
|
|
+ QETH_CARD_TEXT_(card, 4, "simassp%i", prot);
|
|
if (data)
|
|
if (data)
|
|
length = sizeof(__u32);
|
|
length = sizeof(__u32);
|
|
- iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
|
|
|
|
- length, QETH_PROT_IPV4);
|
|
|
|
|
|
+ iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code, length, prot);
|
|
if (!iob)
|
|
if (!iob)
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
rc = qeth_send_setassparms(card, iob, length, data,
|
|
rc = qeth_send_setassparms(card, iob, length, data,
|
|
qeth_setassparms_cb, NULL);
|
|
qeth_setassparms_cb, NULL);
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
-EXPORT_SYMBOL_GPL(qeth_send_simple_setassparms);
|
|
|
|
|
|
+EXPORT_SYMBOL_GPL(qeth_send_simple_setassparms_prot);
|
|
|
|
|
|
static void qeth_unregister_dbf_views(void)
|
|
static void qeth_unregister_dbf_views(void)
|
|
{
|
|
{
|
|
@@ -6008,7 +6010,8 @@ static struct {
|
|
{"tx lin"},
|
|
{"tx lin"},
|
|
{"tx linfail"},
|
|
{"tx linfail"},
|
|
{"cq handler count"},
|
|
{"cq handler count"},
|
|
- {"cq handler time"}
|
|
|
|
|
|
+ {"cq handler time"},
|
|
|
|
+ {"rx csum"}
|
|
};
|
|
};
|
|
|
|
|
|
int qeth_core_get_sset_count(struct net_device *dev, int stringset)
|
|
int qeth_core_get_sset_count(struct net_device *dev, int stringset)
|
|
@@ -6070,6 +6073,7 @@ void qeth_core_get_ethtool_stats(struct net_device *dev,
|
|
data[35] = card->perf_stats.tx_linfail;
|
|
data[35] = card->perf_stats.tx_linfail;
|
|
data[36] = card->perf_stats.cq_cnt;
|
|
data[36] = card->perf_stats.cq_cnt;
|
|
data[37] = card->perf_stats.cq_time;
|
|
data[37] = card->perf_stats.cq_time;
|
|
|
|
+ data[38] = card->perf_stats.rx_csum;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
|
|
EXPORT_SYMBOL_GPL(qeth_core_get_ethtool_stats);
|
|
|
|
|
|
@@ -6326,14 +6330,15 @@ static int qeth_ipa_checksum_run_cmd_cb(struct qeth_card *card,
|
|
static int qeth_ipa_checksum_run_cmd(struct qeth_card *card,
|
|
static int qeth_ipa_checksum_run_cmd(struct qeth_card *card,
|
|
enum qeth_ipa_funcs ipa_func,
|
|
enum qeth_ipa_funcs ipa_func,
|
|
__u16 cmd_code, long data,
|
|
__u16 cmd_code, long data,
|
|
- struct qeth_checksum_cmd *chksum_cb)
|
|
|
|
|
|
+ struct qeth_checksum_cmd *chksum_cb,
|
|
|
|
+ enum qeth_prot_versions prot)
|
|
{
|
|
{
|
|
struct qeth_cmd_buffer *iob;
|
|
struct qeth_cmd_buffer *iob;
|
|
int rc = -ENOMEM;
|
|
int rc = -ENOMEM;
|
|
|
|
|
|
QETH_CARD_TEXT(card, 4, "chkdocmd");
|
|
QETH_CARD_TEXT(card, 4, "chkdocmd");
|
|
iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
|
|
iob = qeth_get_setassparms_cmd(card, ipa_func, cmd_code,
|
|
- sizeof(__u32), QETH_PROT_IPV4);
|
|
|
|
|
|
+ sizeof(__u32), prot);
|
|
if (iob)
|
|
if (iob)
|
|
rc = qeth_send_setassparms(card, iob, sizeof(__u32), data,
|
|
rc = qeth_send_setassparms(card, iob, sizeof(__u32), data,
|
|
qeth_ipa_checksum_run_cmd_cb,
|
|
qeth_ipa_checksum_run_cmd_cb,
|
|
@@ -6341,16 +6346,17 @@ static int qeth_ipa_checksum_run_cmd(struct qeth_card *card,
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
-static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
|
|
|
|
|
|
+static int qeth_send_checksum_on(struct qeth_card *card, int cstype,
|
|
|
|
+ enum qeth_prot_versions prot)
|
|
{
|
|
{
|
|
- const __u32 required_features = QETH_IPA_CHECKSUM_IP_HDR |
|
|
|
|
- QETH_IPA_CHECKSUM_UDP |
|
|
|
|
- QETH_IPA_CHECKSUM_TCP;
|
|
|
|
|
|
+ u32 required_features = QETH_IPA_CHECKSUM_UDP | QETH_IPA_CHECKSUM_TCP;
|
|
struct qeth_checksum_cmd chksum_cb;
|
|
struct qeth_checksum_cmd chksum_cb;
|
|
int rc;
|
|
int rc;
|
|
|
|
|
|
|
|
+ if (prot == QETH_PROT_IPV4)
|
|
|
|
+ required_features |= QETH_IPA_CHECKSUM_IP_HDR;
|
|
rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_START, 0,
|
|
rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_START, 0,
|
|
- &chksum_cb);
|
|
|
|
|
|
+ &chksum_cb, prot);
|
|
if (!rc) {
|
|
if (!rc) {
|
|
if ((required_features & chksum_cb.supported) !=
|
|
if ((required_features & chksum_cb.supported) !=
|
|
required_features)
|
|
required_features)
|
|
@@ -6362,37 +6368,42 @@ static int qeth_send_checksum_on(struct qeth_card *card, int cstype)
|
|
QETH_CARD_IFNAME(card));
|
|
QETH_CARD_IFNAME(card));
|
|
}
|
|
}
|
|
if (rc) {
|
|
if (rc) {
|
|
- qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
|
|
|
|
|
|
+ qeth_send_simple_setassparms_prot(card, cstype,
|
|
|
|
+ IPA_CMD_ASS_STOP, 0, prot);
|
|
dev_warn(&card->gdev->dev,
|
|
dev_warn(&card->gdev->dev,
|
|
- "Starting HW checksumming for %s failed, using SW checksumming\n",
|
|
|
|
- QETH_CARD_IFNAME(card));
|
|
|
|
|
|
+ "Starting HW IPv%d checksumming for %s failed, using SW checksumming\n",
|
|
|
|
+ prot, QETH_CARD_IFNAME(card));
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_ENABLE,
|
|
rc = qeth_ipa_checksum_run_cmd(card, cstype, IPA_CMD_ASS_ENABLE,
|
|
- chksum_cb.supported, &chksum_cb);
|
|
|
|
|
|
+ chksum_cb.supported, &chksum_cb,
|
|
|
|
+ prot);
|
|
if (!rc) {
|
|
if (!rc) {
|
|
if ((required_features & chksum_cb.enabled) !=
|
|
if ((required_features & chksum_cb.enabled) !=
|
|
required_features)
|
|
required_features)
|
|
rc = -EIO;
|
|
rc = -EIO;
|
|
}
|
|
}
|
|
if (rc) {
|
|
if (rc) {
|
|
- qeth_send_simple_setassparms(card, cstype, IPA_CMD_ASS_STOP, 0);
|
|
|
|
|
|
+ qeth_send_simple_setassparms_prot(card, cstype,
|
|
|
|
+ IPA_CMD_ASS_STOP, 0, prot);
|
|
dev_warn(&card->gdev->dev,
|
|
dev_warn(&card->gdev->dev,
|
|
- "Enabling HW checksumming for %s failed, using SW checksumming\n",
|
|
|
|
- QETH_CARD_IFNAME(card));
|
|
|
|
|
|
+ "Enabling HW IPv%d checksumming for %s failed, using SW checksumming\n",
|
|
|
|
+ prot, QETH_CARD_IFNAME(card));
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
- dev_info(&card->gdev->dev, "HW Checksumming (%sbound) enabled\n",
|
|
|
|
- cstype == IPA_INBOUND_CHECKSUM ? "in" : "out");
|
|
|
|
|
|
+ dev_info(&card->gdev->dev, "HW Checksumming (%sbound IPv%d) enabled\n",
|
|
|
|
+ cstype == IPA_INBOUND_CHECKSUM ? "in" : "out", prot);
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int qeth_set_ipa_csum(struct qeth_card *card, int on, int cstype)
|
|
|
|
|
|
+static int qeth_set_ipa_csum(struct qeth_card *card, bool on, int cstype,
|
|
|
|
+ enum qeth_prot_versions prot)
|
|
{
|
|
{
|
|
- int rc = (on) ? qeth_send_checksum_on(card, cstype)
|
|
|
|
- : qeth_send_simple_setassparms(card, cstype,
|
|
|
|
- IPA_CMD_ASS_STOP, 0);
|
|
|
|
|
|
+ int rc = (on) ? qeth_send_checksum_on(card, cstype, prot)
|
|
|
|
+ : qeth_send_simple_setassparms_prot(card, cstype,
|
|
|
|
+ IPA_CMD_ASS_STOP, 0,
|
|
|
|
+ prot);
|
|
return rc ? -EIO : 0;
|
|
return rc ? -EIO : 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -6419,8 +6430,31 @@ static int qeth_set_ipa_tso(struct qeth_card *card, int on)
|
|
return rc;
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
|
|
-#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO)
|
|
|
|
|
|
+static int qeth_set_ipa_rx_csum(struct qeth_card *card, bool on)
|
|
|
|
+{
|
|
|
|
+ int rc_ipv4 = (on) ? -EOPNOTSUPP : 0;
|
|
|
|
+ int rc_ipv6;
|
|
|
|
+
|
|
|
|
+ if (qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
|
|
|
|
+ rc_ipv4 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM,
|
|
|
|
+ QETH_PROT_IPV4);
|
|
|
|
+ if (!qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6))
|
|
|
|
+ /* no/one Offload Assist available, so the rc is trivial */
|
|
|
|
+ return rc_ipv4;
|
|
|
|
|
|
|
|
+ rc_ipv6 = qeth_set_ipa_csum(card, on, IPA_INBOUND_CHECKSUM,
|
|
|
|
+ QETH_PROT_IPV6);
|
|
|
|
+
|
|
|
|
+ if (on)
|
|
|
|
+ /* enable: success if any Assist is active */
|
|
|
|
+ return (rc_ipv6) ? rc_ipv4 : 0;
|
|
|
|
+
|
|
|
|
+ /* disable: failure if any Assist is still active */
|
|
|
|
+ return (rc_ipv6) ? rc_ipv6 : rc_ipv4;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#define QETH_HW_FEATURES (NETIF_F_RXCSUM | NETIF_F_IP_CSUM | NETIF_F_TSO | \
|
|
|
|
+ NETIF_F_IPV6_CSUM)
|
|
/**
|
|
/**
|
|
* qeth_recover_features() - Restore device features after recovery
|
|
* qeth_recover_features() - Restore device features after recovery
|
|
* @dev: the recovering net_device
|
|
* @dev: the recovering net_device
|
|
@@ -6455,16 +6489,19 @@ int qeth_set_features(struct net_device *dev, netdev_features_t features)
|
|
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
|
|
QETH_DBF_HEX(SETUP, 2, &features, sizeof(features));
|
|
|
|
|
|
if ((changed & NETIF_F_IP_CSUM)) {
|
|
if ((changed & NETIF_F_IP_CSUM)) {
|
|
- rc = qeth_set_ipa_csum(card,
|
|
|
|
- features & NETIF_F_IP_CSUM ? 1 : 0,
|
|
|
|
- IPA_OUTBOUND_CHECKSUM);
|
|
|
|
|
|
+ rc = qeth_set_ipa_csum(card, features & NETIF_F_IP_CSUM,
|
|
|
|
+ IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV4);
|
|
if (rc)
|
|
if (rc)
|
|
changed ^= NETIF_F_IP_CSUM;
|
|
changed ^= NETIF_F_IP_CSUM;
|
|
}
|
|
}
|
|
- if ((changed & NETIF_F_RXCSUM)) {
|
|
|
|
- rc = qeth_set_ipa_csum(card,
|
|
|
|
- features & NETIF_F_RXCSUM ? 1 : 0,
|
|
|
|
- IPA_INBOUND_CHECKSUM);
|
|
|
|
|
|
+ if (changed & NETIF_F_IPV6_CSUM) {
|
|
|
|
+ rc = qeth_set_ipa_csum(card, features & NETIF_F_IPV6_CSUM,
|
|
|
|
+ IPA_OUTBOUND_CHECKSUM, QETH_PROT_IPV6);
|
|
|
|
+ if (rc)
|
|
|
|
+ changed ^= NETIF_F_IPV6_CSUM;
|
|
|
|
+ }
|
|
|
|
+ if (changed & NETIF_F_RXCSUM) {
|
|
|
|
+ rc = qeth_set_ipa_rx_csum(card, features & NETIF_F_RXCSUM);
|
|
if (rc)
|
|
if (rc)
|
|
changed ^= NETIF_F_RXCSUM;
|
|
changed ^= NETIF_F_RXCSUM;
|
|
}
|
|
}
|
|
@@ -6491,7 +6528,10 @@ netdev_features_t qeth_fix_features(struct net_device *dev,
|
|
QETH_DBF_TEXT(SETUP, 2, "fixfeat");
|
|
QETH_DBF_TEXT(SETUP, 2, "fixfeat");
|
|
if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
|
|
if (!qeth_is_supported(card, IPA_OUTBOUND_CHECKSUM))
|
|
features &= ~NETIF_F_IP_CSUM;
|
|
features &= ~NETIF_F_IP_CSUM;
|
|
- if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM))
|
|
|
|
|
|
+ if (!qeth_is_supported6(card, IPA_OUTBOUND_CHECKSUM_V6))
|
|
|
|
+ features &= ~NETIF_F_IPV6_CSUM;
|
|
|
|
+ if (!qeth_is_supported(card, IPA_INBOUND_CHECKSUM) &&
|
|
|
|
+ !qeth_is_supported6(card, IPA_INBOUND_CHECKSUM_V6))
|
|
features &= ~NETIF_F_RXCSUM;
|
|
features &= ~NETIF_F_RXCSUM;
|
|
if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
|
|
if (!qeth_is_supported(card, IPA_OUTBOUND_TSO))
|
|
features &= ~NETIF_F_TSO;
|
|
features &= ~NETIF_F_TSO;
|