summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/broadcom/cnic.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/broadcom/cnic.c')
-rw-r--r--drivers/net/ethernet/broadcom/cnic.c91
1 files changed, 45 insertions, 46 deletions
diff --git a/drivers/net/ethernet/broadcom/cnic.c b/drivers/net/ethernet/broadcom/cnic.c
index d78d4cf140ed..4f8a5357cedc 100644
--- a/drivers/net/ethernet/broadcom/cnic.c
+++ b/drivers/net/ethernet/broadcom/cnic.c
@@ -1,6 +1,6 @@
/* cnic.c: Broadcom CNIC core network driver.
*
- * Copyright (c) 2006-2012 Broadcom Corporation
+ * Copyright (c) 2006-2013 Broadcom Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -1427,6 +1427,28 @@ static void cnic_reply_bnx2x_kcqes(struct cnic_dev *dev, int ulp_type,
rcu_read_unlock();
}
+static void cnic_bnx2x_set_tcp_options(struct cnic_dev *dev, int time_stamps,
+ int en_tcp_dack)
+{
+ struct cnic_local *cp = dev->cnic_priv;
+ struct bnx2x *bp = netdev_priv(dev->netdev);
+ u8 xstorm_flags = XSTORM_L5CM_TCP_FLAGS_WND_SCL_EN;
+ u16 tstorm_flags = 0;
+
+ if (time_stamps) {
+ xstorm_flags |= XSTORM_L5CM_TCP_FLAGS_TS_ENABLED;
+ tstorm_flags |= TSTORM_L5CM_TCP_FLAGS_TS_ENABLED;
+ }
+ if (en_tcp_dack)
+ tstorm_flags |= TSTORM_L5CM_TCP_FLAGS_DELAYED_ACK_EN;
+
+ CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
+ XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), xstorm_flags);
+
+ CNIC_WR16(dev, BAR_TSTRORM_INTMEM +
+ TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), tstorm_flags);
+}
+
static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe)
{
struct cnic_local *cp = dev->cnic_priv;
@@ -1506,6 +1528,10 @@ static int cnic_bnx2x_iscsi_init1(struct cnic_dev *dev, struct kwqe *kwqe)
CNIC_WR16(dev, BAR_CSTRORM_INTMEM + CSTORM_ISCSI_HQ_SIZE_OFFSET(pfid),
hq_bds);
+ cnic_bnx2x_set_tcp_options(dev,
+ req1->flags & ISCSI_KWQE_INIT1_TIME_STAMPS_ENABLE,
+ req1->flags & ISCSI_KWQE_INIT1_DELAYED_ACK_ENABLE);
+
return 0;
}
@@ -2035,9 +2061,6 @@ static void cnic_init_storm_conn_bufs(struct cnic_dev *dev,
xstorm_buf->pseudo_header_checksum =
swab16(~csum_ipv6_magic(&src_ip, &dst_ip, 0, IPPROTO_TCP, 0));
- if (!(kwqe1->tcp_flags & L4_KWQ_CONNECT_REQ1_NO_DELAY_ACK))
- tstorm_buf->params |=
- L5CM_TSTORM_CONN_BUFFER_DELAYED_ACK_ENABLE;
if (kwqe3->ka_timeout) {
tstorm_buf->ka_enable = 1;
tstorm_buf->ka_timeout = kwqe3->ka_timeout;
@@ -2084,25 +2107,6 @@ static void cnic_init_bnx2x_mac(struct cnic_dev *dev)
mac[0]);
}
-static void cnic_bnx2x_set_tcp_timestamp(struct cnic_dev *dev, int tcp_ts)
-{
- struct cnic_local *cp = dev->cnic_priv;
- struct bnx2x *bp = netdev_priv(dev->netdev);
- u8 xstorm_flags = XSTORM_L5CM_TCP_FLAGS_WND_SCL_EN;
- u16 tstorm_flags = 0;
-
- if (tcp_ts) {
- xstorm_flags |= XSTORM_L5CM_TCP_FLAGS_TS_ENABLED;
- tstorm_flags |= TSTORM_L5CM_TCP_FLAGS_TS_ENABLED;
- }
-
- CNIC_WR8(dev, BAR_XSTRORM_INTMEM +
- XSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), xstorm_flags);
-
- CNIC_WR16(dev, BAR_TSTRORM_INTMEM +
- TSTORM_ISCSI_TCP_VARS_FLAGS_OFFSET(cp->pfid), tstorm_flags);
-}
-
static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[],
u32 num, int *work)
{
@@ -2178,9 +2182,6 @@ static int cnic_bnx2x_connect(struct cnic_dev *dev, struct kwqe *wqes[],
CNIC_WR16(dev, BAR_XSTRORM_INTMEM +
XSTORM_ISCSI_LOCAL_VLAN_OFFSET(cp->pfid), csk->vlan_id);
- cnic_bnx2x_set_tcp_timestamp(dev,
- kwqe1->tcp_flags & L4_KWQ_CONNECT_REQ1_TIME_STAMP);
-
ret = cnic_submit_kwqe_16(dev, L5CM_RAMROD_CMD_ID_TCP_CONNECT,
kwqe1->cid, ISCSI_CONNECTION_TYPE, &l5_data);
if (!ret)
@@ -3603,6 +3604,7 @@ static int cnic_cm_create(struct cnic_dev *dev, int ulp_type, u32 cid,
csk1->rcv_buf = DEF_RCV_BUF;
csk1->snd_buf = DEF_SND_BUF;
csk1->seed = DEF_SEED;
+ csk1->tcp_flags = 0;
*csk = csk1;
return 0;
@@ -4020,15 +4022,18 @@ static void cnic_cm_process_kcqe(struct cnic_dev *dev, struct kcqe *kcqe)
cnic_cm_upcall(cp, csk, opcode);
break;
- case L5CM_RAMROD_CMD_ID_CLOSE:
- if (l4kcqe->status != 0) {
- netdev_warn(dev->netdev, "RAMROD CLOSE compl with "
- "status 0x%x\n", l4kcqe->status);
+ case L5CM_RAMROD_CMD_ID_CLOSE: {
+ struct iscsi_kcqe *l5kcqe = (struct iscsi_kcqe *) kcqe;
+
+ if (l4kcqe->status != 0 || l5kcqe->completion_status != 0) {
+ netdev_warn(dev->netdev, "RAMROD CLOSE compl with status 0x%x completion status 0x%x\n",
+ l4kcqe->status, l5kcqe->completion_status);
opcode = L4_KCQE_OPCODE_VALUE_CLOSE_COMP;
/* Fall through */
} else {
break;
}
+ }
case L4_KCQE_OPCODE_VALUE_RESET_RECEIVED:
case L4_KCQE_OPCODE_VALUE_CLOSE_COMP:
case L4_KCQE_OPCODE_VALUE_RESET_COMP:
@@ -4219,7 +4224,7 @@ static int cnic_cm_init_bnx2x_hw(struct cnic_dev *dev)
u32 port = CNIC_PORT(cp);
cnic_init_bnx2x_mac(dev);
- cnic_bnx2x_set_tcp_timestamp(dev, 1);
+ cnic_bnx2x_set_tcp_options(dev, 0, 1);
CNIC_WR16(dev, BAR_XSTRORM_INTMEM +
XSTORM_ISCSI_LOCAL_VLAN_OFFSET(pfid), 0);
@@ -5271,6 +5276,13 @@ static int cnic_register_netdev(struct cnic_dev *dev)
if (err)
netdev_err(dev->netdev, "register_cnic failed\n");
+ /* Read iSCSI config again. On some bnx2x device, iSCSI config
+ * can change after firmware is downloaded.
+ */
+ dev->max_iscsi_conn = ethdev->max_iscsi_conn;
+ if (ethdev->drv_state & CNIC_DRV_STATE_NO_ISCSI)
+ dev->max_iscsi_conn = 0;
+
return err;
}
@@ -5628,7 +5640,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
dev = cnic_from_netdev(netdev);
- if (!dev && (event == NETDEV_REGISTER || netif_running(netdev))) {
+ if (!dev && event == NETDEV_REGISTER) {
/* Check for the hot-plug device */
dev = is_cnic_dev(netdev);
if (dev) {
@@ -5644,7 +5656,7 @@ static int cnic_netdev_event(struct notifier_block *this, unsigned long event,
else if (event == NETDEV_UNREGISTER)
cnic_ulp_exit(dev);
- if (event == NETDEV_UP || (new_dev && netif_running(netdev))) {
+ if (event == NETDEV_UP) {
if (cnic_register_netdev(dev) != 0) {
cnic_put(dev);
goto done;
@@ -5693,21 +5705,8 @@ static struct notifier_block cnic_netdev_notifier = {
static void cnic_release(void)
{
- struct cnic_dev *dev;
struct cnic_uio_dev *udev;
- while (!list_empty(&cnic_dev_list)) {
- dev = list_entry(cnic_dev_list.next, struct cnic_dev, list);
- if (test_bit(CNIC_F_CNIC_UP, &dev->flags)) {
- cnic_ulp_stop(dev);
- cnic_stop_hw(dev);
- }
-
- cnic_ulp_exit(dev);
- cnic_unregister_netdev(dev);
- list_del_init(&dev->list);
- cnic_free_dev(dev);
- }
while (!list_empty(&cnic_udev_list)) {
udev = list_entry(cnic_udev_list.next, struct cnic_uio_dev,
list);