qlcnic: driver LRO bug fix
authorManish chopra <manish.chopra@qlogic.com>
Wed, 30 Jan 2013 12:47:15 +0000 (12:47 +0000)
committerDavid S. Miller <davem@davemloft.net>
Thu, 31 Jan 2013 01:34:50 +0000 (20:34 -0500)
o ipv4 address was not getting programmed properly because of
  improper byte order conversion

Signed-off-by: Manish chopra <manish.chopra@qlogic.com>
Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c

index 1e81e94b3c6bf59cb6c4b98fd0ce4237ca2945ce..65233c846537fa472e5f2bb72cc7da31dc975faf 100644 (file)
@@ -1399,7 +1399,7 @@ void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
                               int mode)
 {
        int err;
-       u32 temp;
+       u32 temp, temp_ip;
        struct qlcnic_cmd_args cmd;
 
        qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_IP_ADDR);
@@ -1410,8 +1410,17 @@ void qlcnic_83xx_config_ipaddr(struct qlcnic_adapter *adapter, __be32 ip,
                temp = adapter->recv_ctx->context_id << 16;
                cmd.req.arg[1] = 2 | temp;
        }
-       cmd.req.arg[2] = ntohl(ip);
 
+       /*
+        * Adapter needs IP address in network byte order.
+        * But hardware mailbox registers go through writel(), hence IP address
+        * gets swapped on big endian architecture.
+        * To negate swapping of writel() on big endian architecture
+        * use swab32(value).
+        */
+
+       temp_ip = swab32(ntohl(ip));
+       memcpy(&cmd.req.arg[2], &temp_ip, sizeof(u32));
        err = qlcnic_issue_cmd(adapter, &cmd);
        if (err != QLCNIC_RCODE_SUCCESS)
                dev_err(&adapter->netdev->dev,
@@ -1425,13 +1434,16 @@ int qlcnic_83xx_config_hw_lro(struct qlcnic_adapter *adapter, int mode)
        int err;
        u32 temp, arg1;
        struct qlcnic_cmd_args cmd;
+       int lro_bit_mask;
+
+       lro_bit_mask = (mode ? (BIT_0 | BIT_1 | BIT_2 | BIT_3) : 0);
 
        if (adapter->recv_ctx->state == QLCNIC_HOST_CTX_STATE_FREED)
                return 0;
 
        qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIGURE_HW_LRO);
        temp = adapter->recv_ctx->context_id << 16;
-       arg1 = (mode ? (BIT_0 | BIT_1 | BIT_3) : 0) | temp;
+       arg1 = lro_bit_mask | temp;
        cmd.req.arg[1] = arg1;
 
        err = qlcnic_issue_cmd(adapter, &cmd);
index 6c6ecfc152b8b27fb6283a1b47e22152b9ea72b9..4e4ebafac5c939f5ac4f642abe2750dda2f474f1 100644 (file)
@@ -958,8 +958,10 @@ int qlcnic_set_features(struct net_device *netdev, netdev_features_t features)
        if (qlcnic_config_hw_lro(adapter, hw_lro))
                return -EIO;
 
-       if ((hw_lro == 0) && qlcnic_send_lro_cleanup(adapter))
-               return -EIO;
+       if (!hw_lro && qlcnic_82xx_check(adapter)) {
+               if (qlcnic_send_lro_cleanup(adapter))
+                       return -EIO;
+       }
 
        return 0;
 }