aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulian Wiedmann <jwi@linux.ibm.com>2018-09-17 11:36:04 -0400
committerDavid S. Miller <davem@davemloft.net>2018-09-17 12:10:25 -0400
commit69d7ce80df6d0d2fdbb8f0ff9ec4643aabfa6b99 (patch)
tree8ce99875ee8eb96574f027d108e8aaefd94c3aaa
parent356156b60affae4372ed9d3dc8936ff22e8849b0 (diff)
s390/qeth: remove qeth_hdr_chk_and_bounce()
Restructure the OSN xmit path to handle misaligned HW headers properly, without shifting the packet data around. Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/s390/net/qeth_core.h1
-rw-r--r--drivers/s390/net/qeth_core_main.c21
-rw-r--r--drivers/s390/net/qeth_l2_main.c37
3 files changed, 28 insertions, 31 deletions
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 1c9fce609eb9..be213b5c2552 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -1021,7 +1021,6 @@ void qeth_dbf_longtext(debug_info_t *id, int level, char *text, ...);
1021int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev, 1021int qeth_core_ethtool_get_link_ksettings(struct net_device *netdev,
1022 struct ethtool_link_ksettings *cmd); 1022 struct ethtool_link_ksettings *cmd);
1023int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback); 1023int qeth_set_access_ctrl_online(struct qeth_card *card, int fallback);
1024int qeth_hdr_chk_and_bounce(struct sk_buff *, struct qeth_hdr **, int);
1025int qeth_configure_cq(struct qeth_card *, enum qeth_cq); 1024int qeth_configure_cq(struct qeth_card *, enum qeth_cq);
1026int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action); 1025int qeth_hw_trap(struct qeth_card *, enum qeth_diags_trap_action);
1027void qeth_trace_features(struct qeth_card *); 1026void qeth_trace_features(struct qeth_card *);
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 7426167eace2..c7f7061a7205 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3823,27 +3823,6 @@ unsigned int qeth_count_elements(struct sk_buff *skb, unsigned int data_offset)
3823} 3823}
3824EXPORT_SYMBOL_GPL(qeth_count_elements); 3824EXPORT_SYMBOL_GPL(qeth_count_elements);
3825 3825
3826int qeth_hdr_chk_and_bounce(struct sk_buff *skb, struct qeth_hdr **hdr, int len)
3827{
3828 int hroom, inpage, rest;
3829
3830 if (((unsigned long)skb->data & PAGE_MASK) !=
3831 (((unsigned long)skb->data + len - 1) & PAGE_MASK)) {
3832 hroom = skb_headroom(skb);
3833 inpage = PAGE_SIZE - ((unsigned long) skb->data % PAGE_SIZE);
3834 rest = len - inpage;
3835 if (rest > hroom)
3836 return 1;
3837 memmove(skb->data - rest, skb->data, skb_headlen(skb));
3838 skb->data -= rest;
3839 skb->tail -= rest;
3840 *hdr = (struct qeth_hdr *)skb->data;
3841 QETH_DBF_MESSAGE(2, "skb bounce len: %d rest: %d\n", len, rest);
3842 }
3843 return 0;
3844}
3845EXPORT_SYMBOL_GPL(qeth_hdr_chk_and_bounce);
3846
3847#define QETH_HDR_CACHE_OBJ_SIZE (sizeof(struct qeth_hdr_tso) + \ 3826#define QETH_HDR_CACHE_OBJ_SIZE (sizeof(struct qeth_hdr_tso) + \
3848 MAX_TCP_HEADER) 3827 MAX_TCP_HEADER)
3849 3828
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 24b531ca2827..33b65471a68a 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -650,19 +650,38 @@ static void qeth_l2_set_rx_mode(struct net_device *dev)
650static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb, 650static int qeth_l2_xmit_osn(struct qeth_card *card, struct sk_buff *skb,
651 struct qeth_qdio_out_q *queue) 651 struct qeth_qdio_out_q *queue)
652{ 652{
653 unsigned int elements; 653 struct qeth_hdr *hdr = (struct qeth_hdr *)skb->data;
654 struct qeth_hdr *hdr; 654 addr_t end = (addr_t)(skb->data + sizeof(*hdr));
655 addr_t start = (addr_t)skb->data;
656 unsigned int elements = 0;
657 unsigned int hd_len = 0;
658 int rc;
655 659
656 if (skb->protocol == htons(ETH_P_IPV6)) 660 if (skb->protocol == htons(ETH_P_IPV6))
657 return -EPROTONOSUPPORT; 661 return -EPROTONOSUPPORT;
658 662
659 hdr = (struct qeth_hdr *)skb->data; 663 if (qeth_get_elements_for_range(start, end) > 1) {
660 elements = qeth_count_elements(skb, 0); 664 /* Misaligned HW header, move it to its own buffer element. */
661 if (elements > QETH_MAX_BUFFER_ELEMENTS(card)) 665 hdr = kmem_cache_alloc(qeth_core_header_cache, GFP_ATOMIC);
662 return -E2BIG; 666 if (!hdr)
663 if (qeth_hdr_chk_and_bounce(skb, &hdr, sizeof(*hdr))) 667 return -ENOMEM;
664 return -EINVAL; 668 hd_len = sizeof(*hdr);
665 return qeth_do_send_packet(card, queue, skb, hdr, 0, 0, elements); 669 skb_copy_from_linear_data(skb, (char *)hdr, hd_len);
670 elements++;
671 }
672
673 elements += qeth_count_elements(skb, hd_len);
674 if (elements > QETH_MAX_BUFFER_ELEMENTS(card)) {
675 rc = -E2BIG;
676 goto out;
677 }
678
679 rc = qeth_do_send_packet(card, queue, skb, hdr, hd_len, hd_len,
680 elements);
681out:
682 if (rc && hd_len)
683 kmem_cache_free(qeth_core_header_cache, hdr);
684 return rc;
666} 685}
667 686
668static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb, 687static netdev_tx_t qeth_l2_hard_start_xmit(struct sk_buff *skb,