Re: [net-next PATCH] ibmvnic: map L2/L3/L4 header descriptors to firmware

2016-02-24 Thread kbuild test robot
Hi Thomas,

[auto build test ERROR on net-next/master]

url:
https://github.com/0day-ci/linux/commits/Thomas-Falcon/ibmvnic-map-L2-L3-L4-header-descriptors-to-firmware/20160225-033734
config: powerpc-allmodconfig (attached as .config)
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=powerpc 

All error/warnings (new ones prefixed by >>):

   drivers/net/ethernet/ibm/ibmvnic.c: In function 'build_hdr_descs_arr':
>> drivers/net/ethernet/ibm/ibmvnic.c:712:13: error: implicit declaration of 
>> function 'bld_hdr_data' [-Werror=implicit-function-declaration]
 hdr_data = bld_hdr_data(hdr_field, skb, hdr_len, &tot_len);
^
>> drivers/net/ethernet/ibm/ibmvnic.c:712:11: warning: assignment makes pointer 
>> from integer without a cast [-Wint-conversion]
 hdr_data = bld_hdr_data(hdr_field, skb, hdr_len, &tot_len);
  ^
   drivers/net/ethernet/ibm/ibmvnic.c: At top level:
   drivers/net/ethernet/ibm/ibmvnic.c:577:23: warning: 'build_hdr_data' defined 
but not used [-Wunused-function]
static unsigned char *build_hdr_data(u8 hdr_field, struct sk_buff *skb,
  ^
   cc1: some warnings being treated as errors

vim +/bld_hdr_data +712 drivers/net/ethernet/ibm/ibmvnic.c

   706  {
   707  unsigned char *hdr_data;
   708  union sub_crq *entries;
   709  int hdr_len[3] = {0};
   710  int tot_len;
   711  
 > 712  hdr_data = bld_hdr_data(hdr_field, skb, hdr_len, &tot_len);
   713  if (!hdr_data)
   714  return NULL;
   715  

---
0-DAY kernel test infrastructureOpen Source Technology Center
https://lists.01.org/pipermail/kbuild-all   Intel Corporation


.config.gz
Description: Binary data
___
Linuxppc-dev mailing list
Linuxppc-dev@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/linuxppc-dev

[net-next PATCH] ibmvnic: map L2/L3/L4 header descriptors to firmware

2016-02-24 Thread Thomas Falcon
Allow the VNIC driver to provide descriptors containing
L2/L3/L4 headers to firmware.  This feature is needed
for greater hardware compatibility and enablement of offloading
technologies for some backing hardware.

Signed-off-by: Thomas Falcon 
---
 drivers/net/ethernet/ibm/ibmvnic.c | 238 -
 1 file changed, 235 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
index 7d657084..43c1df6 100644
--- a/drivers/net/ethernet/ibm/ibmvnic.c
+++ b/drivers/net/ethernet/ibm/ibmvnic.c
@@ -61,6 +61,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -94,6 +95,7 @@ static int ibmvnic_reenable_crq_queue(struct ibmvnic_adapter 
*);
 static int ibmvnic_send_crq(struct ibmvnic_adapter *, union ibmvnic_crq *);
 static int send_subcrq(struct ibmvnic_adapter *adapter, u64 remote_handle,
   union sub_crq *sub_crq);
+static int send_subcrq_indirect(struct ibmvnic_adapter *, u64, u64, u64);
 static irqreturn_t ibmvnic_interrupt_rx(int irq, void *instance);
 static int enable_scrq_irq(struct ibmvnic_adapter *,
   struct ibmvnic_sub_crq_queue *);
@@ -561,12 +563,177 @@ static int ibmvnic_close(struct net_device *netdev)
return 0;
 }
 
+/**
+ * build_hdr_data - creates L2/L3/L4 header data buffer
+ * @hdr_field - bitfield determining needed headers
+ * @skb - socket buffer
+ * @hdr_len - array of header lengths
+ * @tot_len - total length of data
+ *
+ * Reads hdr_field to determine which headers are needed by firmware.
+ * Builds a buffer containing these headers.  Saves individual header
+ * lengths and total buffer length to be used to build descriptors.
+ */
+static unsigned char *build_hdr_data(u8 hdr_field, struct sk_buff *skb,
+int *hdr_len, int *tot_len)
+{
+   unsigned char *hdr_data;
+   unsigned char *hdrs[3];
+   u8 proto = 0;
+   int len = 0;
+   int i;
+
+   if ((hdr_field >> 6) & 1) {
+   hdrs[0] = skb_mac_header(skb);
+   hdr_len[0] = sizeof(struct ethhdr);
+   }
+
+   if ((hdr_field >> 5) & 1) {
+   hdrs[1] = skb_network_header(skb);
+   if (skb->protocol == htons(ETH_P_IP))
+   hdr_len[1] = ip_hdr(skb)->ihl * 4;
+   else if (skb->protocol == htons(ETH_P_IPV6))
+   hdr_len[1] = sizeof(struct ipv6hdr);
+   }
+
+   if ((hdr_field >> 4) & 1) {
+   hdrs[2] = skb_transport_header(skb);
+   if (skb->protocol == htons(ETH_P_IP))
+   proto = ip_hdr(skb)->protocol;
+   else if (skb->protocol == htons(ETH_P_IPV6))
+   proto = ipv6_hdr(skb)->nexthdr;
+
+   if (proto == IPPROTO_TCP)
+   hdr_len[2] = tcp_hdrlen(skb);
+   else if (proto == IPPROTO_UDP)
+   hdr_len[2] = sizeof(struct udphdr);
+   }
+
+   *tot_len = hdr_len[0] + hdr_len[1] + hdr_len[2];
+
+   hdr_data = kmalloc(*tot_len, GFP_KERNEL);
+   if (!hdr_data)
+   return NULL;
+
+   for (i = 0; i < 3; i++) {
+   if (hdrs[i])
+   memcpy(hdr_data, hdrs[i] + len, hdr_len[i]);
+   len += hdr_len[i];
+   }
+   return hdr_data;
+}
+
+/**
+ * create_hdr_descs - create header and header extension descriptors
+ * @hdr_field - bitfield determining needed headers
+ * @data - buffer containing header data
+ * @len - length of data buffer
+ * @hdr_len - array of individual header lengths
+ * @scrq_arr - descriptor array
+ *
+ * Creates header and, if needed, header extension descriptors and
+ * places them in a descriptor array, scrq_arr
+ */
+
+void create_hdr_descs(u8 hdr_field, unsigned char *data, int len, int *hdr_len,
+ union sub_crq *scrq_arr)
+{
+   union sub_crq hdr_desc;
+   int tmp_len = len;
+   int tmp;
+
+   while (tmp_len > 0) {
+   unsigned char *cur = data + len - tmp_len;
+
+   memset(&hdr_desc, 0, sizeof(hdr_desc));
+   if (cur != data) {
+   tmp = tmp_len > 29 ? 29 : tmp_len;
+   hdr_desc.hdr_ext.first = IBMVNIC_CRQ_CMD;
+   hdr_desc.hdr_ext.type = IBMVNIC_HDR_EXT_DESC;
+   hdr_desc.hdr_ext.len = tmp;
+   } else {
+   tmp = tmp_len > 24 ? 24 : tmp_len;
+   hdr_desc.hdr.first = IBMVNIC_CRQ_CMD;
+   hdr_desc.hdr.type = IBMVNIC_HDR_DESC;
+   hdr_desc.hdr.len = tmp;
+   hdr_desc.hdr.l2_len = (u8)hdr_len[0];
+   hdr_desc.hdr.l3_len = (u16)hdr_len[1];
+   hdr_desc.hdr.l4_len = (u8)hdr_len[2];
+   hdr_desc.hdr.flag = hdr_field << 1;
+   }
+   memcpy(hdr_de