diff options
Diffstat (limited to 'drivers/infiniband/hw/i40iw/i40iw_cm.c')
-rw-r--r-- | drivers/infiniband/hw/i40iw/i40iw_cm.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/drivers/infiniband/hw/i40iw/i40iw_cm.c b/drivers/infiniband/hw/i40iw/i40iw_cm.c index 5230dd3c938c..493d6ef3d2d5 100644 --- a/drivers/infiniband/hw/i40iw/i40iw_cm.c +++ b/drivers/infiniband/hw/i40iw/i40iw_cm.c @@ -1188,7 +1188,7 @@ static void i40iw_handle_close_entry(struct i40iw_cm_node *cm_node, u32 rem_node * i40iw_cm_timer_tick - system's timer expired callback * @pass: Pointing to cm_core */ -static void i40iw_cm_timer_tick(unsigned long pass) +static void i40iw_cm_timer_tick(struct timer_list *t) { unsigned long nexttimeout = jiffies + I40IW_LONG_TIME; struct i40iw_cm_node *cm_node; @@ -1196,10 +1196,9 @@ static void i40iw_cm_timer_tick(unsigned long pass) struct list_head *list_core_temp; struct i40iw_sc_vsi *vsi; struct list_head *list_node; - struct i40iw_cm_core *cm_core = (struct i40iw_cm_core *)pass; + struct i40iw_cm_core *cm_core = from_timer(cm_core, t, tcp_timer); u32 settimer = 0; unsigned long timetosend; - struct i40iw_sc_dev *dev; unsigned long flags; struct list_head timer_list; @@ -1267,13 +1266,15 @@ static void i40iw_cm_timer_tick(unsigned long pass) spin_lock_irqsave(&cm_node->retrans_list_lock, flags); goto done; } - cm_node->cm_core->stats_pkt_retrans++; spin_unlock_irqrestore(&cm_node->retrans_list_lock, flags); vsi = &cm_node->iwdev->vsi; - dev = cm_node->dev; - atomic_inc(&send_entry->sqbuf->refcount); - i40iw_puda_send_buf(vsi->ilq, send_entry->sqbuf); + + if (!cm_node->ack_rcvd) { + atomic_inc(&send_entry->sqbuf->refcount); + i40iw_puda_send_buf(vsi->ilq, send_entry->sqbuf); + cm_node->cm_core->stats_pkt_retrans++; + } spin_lock_irqsave(&cm_node->retrans_list_lock, flags); if (send_entry->send_retrans) { send_entry->retranscount--; @@ -1524,8 +1525,8 @@ static bool i40iw_port_in_use(struct i40iw_cm_core *cm_core, u16 port, bool acti break; } } - if (!ret) - clear_bit(port, cm_core->active_side_ports); + if (!ret) + clear_bit(port, cm_core->active_side_ports); spin_unlock_irqrestore(&cm_core->ht_lock, flags); } else { spin_lock_irqsave(&cm_core->listen_list_lock, flags); @@ -2181,6 +2182,7 @@ static struct i40iw_cm_node *i40iw_make_cm_node( cm_node->cm_id = cm_info->cm_id; ether_addr_copy(cm_node->loc_mac, netdev->dev_addr); spin_lock_init(&cm_node->retrans_list_lock); + cm_node->ack_rcvd = false; atomic_set(&cm_node->ref_count, 1); /* associate our parent CM core */ @@ -2191,7 +2193,8 @@ static struct i40iw_cm_node *i40iw_make_cm_node( I40IW_CM_DEFAULT_RCV_WND_SCALED >> I40IW_CM_DEFAULT_RCV_WND_SCALE; ts = current_kernel_time(); cm_node->tcp_cntxt.loc_seq_num = ts.tv_nsec; - cm_node->tcp_cntxt.mss = iwdev->vsi.mss; + cm_node->tcp_cntxt.mss = (cm_node->ipv4) ? (iwdev->vsi.mtu - I40IW_MTU_TO_MSS_IPV4) : + (iwdev->vsi.mtu - I40IW_MTU_TO_MSS_IPV6); cm_node->iwdev = iwdev; cm_node->dev = &iwdev->sc_dev; @@ -2406,6 +2409,7 @@ static void i40iw_handle_rst_pkt(struct i40iw_cm_node *cm_node, case I40IW_CM_STATE_FIN_WAIT1: case I40IW_CM_STATE_LAST_ACK: cm_node->cm_id->rem_ref(cm_node->cm_id); + /* fall through */ case I40IW_CM_STATE_TIME_WAIT: cm_node->state = I40IW_CM_STATE_CLOSED; i40iw_rem_ref_cm_node(cm_node); @@ -2719,7 +2723,10 @@ static int i40iw_handle_ack_pkt(struct i40iw_cm_node *cm_node, cm_node->tcp_cntxt.rem_ack_num = ntohl(tcph->ack_seq); if (datasize) { cm_node->tcp_cntxt.rcv_nxt = inc_sequence + datasize; + cm_node->ack_rcvd = false; i40iw_handle_rcv_mpa(cm_node, rbuf); + } else { + cm_node->ack_rcvd = true; } break; case I40IW_CM_STATE_LISTENING: @@ -3195,8 +3202,7 @@ void i40iw_setup_cm_core(struct i40iw_device *iwdev) INIT_LIST_HEAD(&cm_core->connected_nodes); INIT_LIST_HEAD(&cm_core->listen_nodes); - setup_timer(&cm_core->tcp_timer, i40iw_cm_timer_tick, - (unsigned long)cm_core); + timer_setup(&cm_core->tcp_timer, i40iw_cm_timer_tick, 0); spin_lock_init(&cm_core->ht_lock); spin_lock_init(&cm_core->listen_list_lock); |