diff options
Diffstat (limited to 'drivers/infiniband/hw/nes')
-rw-r--r-- | drivers/infiniband/hw/nes/nes.c | 42 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes.h | 4 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_cm.c | 39 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 112 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.h | 11 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_nic.c | 144 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_verbs.c | 59 |
7 files changed, 302 insertions, 109 deletions
diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c index 0c9f0aa5d4ea..2d668c69f6d9 100644 --- a/drivers/infiniband/hw/nes/nes.c +++ b/drivers/infiniband/hw/nes/nes.c | |||
@@ -144,6 +144,7 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
144 | struct nes_device *nesdev; | 144 | struct nes_device *nesdev; |
145 | struct net_device *netdev; | 145 | struct net_device *netdev; |
146 | struct nes_vnic *nesvnic; | 146 | struct nes_vnic *nesvnic; |
147 | unsigned int is_bonded; | ||
147 | 148 | ||
148 | nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %pI4, netmask %pI4.\n", | 149 | nes_debug(NES_DBG_NETDEV, "nes_inetaddr_event: ip address %pI4, netmask %pI4.\n", |
149 | &ifa->ifa_address, &ifa->ifa_mask); | 150 | &ifa->ifa_address, &ifa->ifa_mask); |
@@ -152,7 +153,9 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
152 | nesdev, nesdev->netdev[0]->name); | 153 | nesdev, nesdev->netdev[0]->name); |
153 | netdev = nesdev->netdev[0]; | 154 | netdev = nesdev->netdev[0]; |
154 | nesvnic = netdev_priv(netdev); | 155 | nesvnic = netdev_priv(netdev); |
155 | if (netdev == event_netdev) { | 156 | is_bonded = netif_is_bond_slave(netdev) && |
157 | (netdev->master == event_netdev); | ||
158 | if ((netdev == event_netdev) || is_bonded) { | ||
156 | if (nesvnic->rdma_enabled == 0) { | 159 | if (nesvnic->rdma_enabled == 0) { |
157 | nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" | 160 | nes_debug(NES_DBG_NETDEV, "Returning without processing event for %s since" |
158 | " RDMA is not enabled.\n", | 161 | " RDMA is not enabled.\n", |
@@ -169,7 +172,10 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
169 | nes_manage_arp_cache(netdev, netdev->dev_addr, | 172 | nes_manage_arp_cache(netdev, netdev->dev_addr, |
170 | ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE); | 173 | ntohl(nesvnic->local_ipaddr), NES_ARP_DELETE); |
171 | nesvnic->local_ipaddr = 0; | 174 | nesvnic->local_ipaddr = 0; |
172 | return NOTIFY_OK; | 175 | if (is_bonded) |
176 | continue; | ||
177 | else | ||
178 | return NOTIFY_OK; | ||
173 | break; | 179 | break; |
174 | case NETDEV_UP: | 180 | case NETDEV_UP: |
175 | nes_debug(NES_DBG_NETDEV, "event:UP\n"); | 181 | nes_debug(NES_DBG_NETDEV, "event:UP\n"); |
@@ -178,15 +184,24 @@ static int nes_inetaddr_event(struct notifier_block *notifier, | |||
178 | nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n"); | 184 | nes_debug(NES_DBG_NETDEV, "Interface already has local_ipaddr\n"); |
179 | return NOTIFY_OK; | 185 | return NOTIFY_OK; |
180 | } | 186 | } |
187 | /* fall through */ | ||
188 | case NETDEV_CHANGEADDR: | ||
181 | /* Add the address to the IP table */ | 189 | /* Add the address to the IP table */ |
182 | nesvnic->local_ipaddr = ifa->ifa_address; | 190 | if (netdev->master) |
191 | nesvnic->local_ipaddr = | ||
192 | ((struct in_device *)netdev->master->ip_ptr)->ifa_list->ifa_address; | ||
193 | else | ||
194 | nesvnic->local_ipaddr = ifa->ifa_address; | ||
183 | 195 | ||
184 | nes_write_indexed(nesdev, | 196 | nes_write_indexed(nesdev, |
185 | NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), | 197 | NES_IDX_DST_IP_ADDR+(0x10*PCI_FUNC(nesdev->pcidev->devfn)), |
186 | ntohl(ifa->ifa_address)); | 198 | ntohl(nesvnic->local_ipaddr)); |
187 | nes_manage_arp_cache(netdev, netdev->dev_addr, | 199 | nes_manage_arp_cache(netdev, netdev->dev_addr, |
188 | ntohl(nesvnic->local_ipaddr), NES_ARP_ADD); | 200 | ntohl(nesvnic->local_ipaddr), NES_ARP_ADD); |
189 | return NOTIFY_OK; | 201 | if (is_bonded) |
202 | continue; | ||
203 | else | ||
204 | return NOTIFY_OK; | ||
190 | break; | 205 | break; |
191 | default: | 206 | default: |
192 | break; | 207 | break; |
@@ -660,6 +675,8 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
660 | } | 675 | } |
661 | nes_notifiers_registered++; | 676 | nes_notifiers_registered++; |
662 | 677 | ||
678 | INIT_DELAYED_WORK(&nesdev->work, nes_recheck_link_status); | ||
679 | |||
663 | /* Initialize network devices */ | 680 | /* Initialize network devices */ |
664 | if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL) | 681 | if ((netdev = nes_netdev_init(nesdev, mmio_regs)) == NULL) |
665 | goto bail7; | 682 | goto bail7; |
@@ -677,7 +694,7 @@ static int __devinit nes_probe(struct pci_dev *pcidev, const struct pci_device_i | |||
677 | nesdev->netdev_count++; | 694 | nesdev->netdev_count++; |
678 | nesdev->nesadapter->netdev_count++; | 695 | nesdev->nesadapter->netdev_count++; |
679 | 696 | ||
680 | printk(KERN_ERR PFX "%s: NetEffect RNIC driver successfully loaded.\n", | 697 | printk(KERN_INFO PFX "%s: NetEffect RNIC driver successfully loaded.\n", |
681 | pci_name(pcidev)); | 698 | pci_name(pcidev)); |
682 | return 0; | 699 | return 0; |
683 | 700 | ||
@@ -742,6 +759,7 @@ static void __devexit nes_remove(struct pci_dev *pcidev) | |||
742 | struct nes_device *nesdev = pci_get_drvdata(pcidev); | 759 | struct nes_device *nesdev = pci_get_drvdata(pcidev); |
743 | struct net_device *netdev; | 760 | struct net_device *netdev; |
744 | int netdev_index = 0; | 761 | int netdev_index = 0; |
762 | unsigned long flags; | ||
745 | 763 | ||
746 | if (nesdev->netdev_count) { | 764 | if (nesdev->netdev_count) { |
747 | netdev = nesdev->netdev[netdev_index]; | 765 | netdev = nesdev->netdev[netdev_index]; |
@@ -768,6 +786,14 @@ static void __devexit nes_remove(struct pci_dev *pcidev) | |||
768 | free_irq(pcidev->irq, nesdev); | 786 | free_irq(pcidev->irq, nesdev); |
769 | tasklet_kill(&nesdev->dpc_tasklet); | 787 | tasklet_kill(&nesdev->dpc_tasklet); |
770 | 788 | ||
789 | spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); | ||
790 | if (nesdev->link_recheck) { | ||
791 | spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); | ||
792 | cancel_delayed_work_sync(&nesdev->work); | ||
793 | } else { | ||
794 | spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); | ||
795 | } | ||
796 | |||
771 | /* Deallocate the Adapter Structure */ | 797 | /* Deallocate the Adapter Structure */ |
772 | nes_destroy_adapter(nesdev->nesadapter); | 798 | nes_destroy_adapter(nesdev->nesadapter); |
773 | 799 | ||
@@ -1112,7 +1138,9 @@ static ssize_t nes_store_wqm_quanta(struct device_driver *ddp, | |||
1112 | u32 i = 0; | 1138 | u32 i = 0; |
1113 | struct nes_device *nesdev; | 1139 | struct nes_device *nesdev; |
1114 | 1140 | ||
1115 | strict_strtoul(buf, 0, &wqm_quanta_value); | 1141 | if (kstrtoul(buf, 0, &wqm_quanta_value) < 0) |
1142 | return -EINVAL; | ||
1143 | |||
1116 | list_for_each_entry(nesdev, &nes_dev_list, list) { | 1144 | list_for_each_entry(nesdev, &nes_dev_list, list) { |
1117 | if (i == ee_flsh_adapter) { | 1145 | if (i == ee_flsh_adapter) { |
1118 | nesdev->nesadapter->wqm_quanta = wqm_quanta_value; | 1146 | nesdev->nesadapter->wqm_quanta = wqm_quanta_value; |
diff --git a/drivers/infiniband/hw/nes/nes.h b/drivers/infiniband/hw/nes/nes.h index b3d145e82b4c..6fe79876009e 100644 --- a/drivers/infiniband/hw/nes/nes.h +++ b/drivers/infiniband/hw/nes/nes.h | |||
@@ -268,6 +268,9 @@ struct nes_device { | |||
268 | u8 napi_isr_ran; | 268 | u8 napi_isr_ran; |
269 | u8 disable_rx_flow_control; | 269 | u8 disable_rx_flow_control; |
270 | u8 disable_tx_flow_control; | 270 | u8 disable_tx_flow_control; |
271 | |||
272 | struct delayed_work work; | ||
273 | u8 link_recheck; | ||
271 | }; | 274 | }; |
272 | 275 | ||
273 | 276 | ||
@@ -507,6 +510,7 @@ void nes_nic_ce_handler(struct nes_device *, struct nes_hw_nic_cq *); | |||
507 | void nes_iwarp_ce_handler(struct nes_device *, struct nes_hw_cq *); | 510 | void nes_iwarp_ce_handler(struct nes_device *, struct nes_hw_cq *); |
508 | int nes_destroy_cqp(struct nes_device *); | 511 | int nes_destroy_cqp(struct nes_device *); |
509 | int nes_nic_cm_xmit(struct sk_buff *, struct net_device *); | 512 | int nes_nic_cm_xmit(struct sk_buff *, struct net_device *); |
513 | void nes_recheck_link_status(struct work_struct *work); | ||
510 | 514 | ||
511 | /* nes_nic.c */ | 515 | /* nes_nic.c */ |
512 | struct net_device *nes_netdev_init(struct nes_device *, void __iomem *); | 516 | struct net_device *nes_netdev_init(struct nes_device *, void __iomem *); |
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c index 61e0efd4ccfb..e74cdf9ef471 100644 --- a/drivers/infiniband/hw/nes/nes_cm.c +++ b/drivers/infiniband/hw/nes/nes_cm.c | |||
@@ -1104,20 +1104,24 @@ static inline int mini_cm_accelerated(struct nes_cm_core *cm_core, | |||
1104 | static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex) | 1104 | static int nes_addr_resolve_neigh(struct nes_vnic *nesvnic, u32 dst_ip, int arpindex) |
1105 | { | 1105 | { |
1106 | struct rtable *rt; | 1106 | struct rtable *rt; |
1107 | struct flowi fl; | ||
1108 | struct neighbour *neigh; | 1107 | struct neighbour *neigh; |
1109 | int rc = arpindex; | 1108 | int rc = arpindex; |
1109 | struct net_device *netdev; | ||
1110 | struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; | 1110 | struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; |
1111 | 1111 | ||
1112 | memset(&fl, 0, sizeof fl); | 1112 | rt = ip_route_output(&init_net, htonl(dst_ip), 0, 0, 0); |
1113 | fl.nl_u.ip4_u.daddr = htonl(dst_ip); | 1113 | if (IS_ERR(rt)) { |
1114 | if (ip_route_output_key(&init_net, &rt, &fl)) { | ||
1115 | printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n", | 1114 | printk(KERN_ERR "%s: ip_route_output_key failed for 0x%08X\n", |
1116 | __func__, dst_ip); | 1115 | __func__, dst_ip); |
1117 | return rc; | 1116 | return rc; |
1118 | } | 1117 | } |
1119 | 1118 | ||
1120 | neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, nesvnic->netdev); | 1119 | if (netif_is_bond_slave(nesvnic->netdev)) |
1120 | netdev = nesvnic->netdev->master; | ||
1121 | else | ||
1122 | netdev = nesvnic->netdev; | ||
1123 | |||
1124 | neigh = neigh_lookup(&arp_tbl, &rt->rt_gateway, netdev); | ||
1121 | if (neigh) { | 1125 | if (neigh) { |
1122 | if (neigh->nud_state & NUD_VALID) { | 1126 | if (neigh->nud_state & NUD_VALID) { |
1123 | nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" | 1127 | nes_debug(NES_DBG_CM, "Neighbor MAC address for 0x%08X" |
@@ -1393,7 +1397,7 @@ static void handle_fin_pkt(struct nes_cm_node *cm_node) | |||
1393 | cleanup_retrans_entry(cm_node); | 1397 | cleanup_retrans_entry(cm_node); |
1394 | cm_node->state = NES_CM_STATE_CLOSING; | 1398 | cm_node->state = NES_CM_STATE_CLOSING; |
1395 | send_ack(cm_node, NULL); | 1399 | send_ack(cm_node, NULL); |
1396 | /* Wait for ACK as this is simultanous close.. | 1400 | /* Wait for ACK as this is simultaneous close.. |
1397 | * After we receive ACK, do not send anything.. | 1401 | * After we receive ACK, do not send anything.. |
1398 | * Just rm the node.. Done.. */ | 1402 | * Just rm the node.. Done.. */ |
1399 | break; | 1403 | break; |
@@ -1424,7 +1428,6 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1424 | { | 1428 | { |
1425 | 1429 | ||
1426 | int reset = 0; /* whether to send reset in case of err.. */ | 1430 | int reset = 0; /* whether to send reset in case of err.. */ |
1427 | int passive_state; | ||
1428 | atomic_inc(&cm_resets_recvd); | 1431 | atomic_inc(&cm_resets_recvd); |
1429 | nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u." | 1432 | nes_debug(NES_DBG_CM, "Received Reset, cm_node = %p, state = %u." |
1430 | " refcnt=%d\n", cm_node, cm_node->state, | 1433 | " refcnt=%d\n", cm_node, cm_node->state, |
@@ -1439,7 +1442,7 @@ static void handle_rst_pkt(struct nes_cm_node *cm_node, struct sk_buff *skb, | |||
1439 | active_open_err(cm_node, skb, reset); | 1442 | active_open_err(cm_node, skb, reset); |
1440 | break; | 1443 | break; |
1441 | case NES_CM_STATE_MPAREQ_RCVD: | 1444 | case NES_CM_STATE_MPAREQ_RCVD: |
1442 | passive_state = atomic_add_return(1, &cm_node->passive_state); | 1445 | atomic_inc(&cm_node->passive_state); |
1443 | dev_kfree_skb_any(skb); | 1446 | dev_kfree_skb_any(skb); |
1444 | break; | 1447 | break; |
1445 | case NES_CM_STATE_ESTABLISHED: | 1448 | case NES_CM_STATE_ESTABLISHED: |
@@ -2560,7 +2563,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
2560 | u16 last_ae; | 2563 | u16 last_ae; |
2561 | u8 original_hw_tcp_state; | 2564 | u8 original_hw_tcp_state; |
2562 | u8 original_ibqp_state; | 2565 | u8 original_ibqp_state; |
2563 | enum iw_cm_event_status disconn_status = IW_CM_EVENT_STATUS_OK; | 2566 | int disconn_status = 0; |
2564 | int issue_disconn = 0; | 2567 | int issue_disconn = 0; |
2565 | int issue_close = 0; | 2568 | int issue_close = 0; |
2566 | int issue_flush = 0; | 2569 | int issue_flush = 0; |
@@ -2602,7 +2605,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
2602 | (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { | 2605 | (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET))) { |
2603 | issue_disconn = 1; | 2606 | issue_disconn = 1; |
2604 | if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) | 2607 | if (last_ae == NES_AEQE_AEID_LLP_CONNECTION_RESET) |
2605 | disconn_status = IW_CM_EVENT_STATUS_RESET; | 2608 | disconn_status = -ECONNRESET; |
2606 | } | 2609 | } |
2607 | 2610 | ||
2608 | if (((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) || | 2611 | if (((original_hw_tcp_state == NES_AEQE_TCP_STATE_CLOSED) || |
@@ -2663,7 +2666,7 @@ static int nes_cm_disconn_true(struct nes_qp *nesqp) | |||
2663 | cm_id->provider_data = nesqp; | 2666 | cm_id->provider_data = nesqp; |
2664 | /* Send up the close complete event */ | 2667 | /* Send up the close complete event */ |
2665 | cm_event.event = IW_CM_EVENT_CLOSE; | 2668 | cm_event.event = IW_CM_EVENT_CLOSE; |
2666 | cm_event.status = IW_CM_EVENT_STATUS_OK; | 2669 | cm_event.status = 0; |
2667 | cm_event.provider_data = cm_id->provider_data; | 2670 | cm_event.provider_data = cm_id->provider_data; |
2668 | cm_event.local_addr = cm_id->local_addr; | 2671 | cm_event.local_addr = cm_id->local_addr; |
2669 | cm_event.remote_addr = cm_id->remote_addr; | 2672 | cm_event.remote_addr = cm_id->remote_addr; |
@@ -2701,7 +2704,7 @@ static int nes_disconnect(struct nes_qp *nesqp, int abrupt) | |||
2701 | nesibdev = nesvnic->nesibdev; | 2704 | nesibdev = nesvnic->nesibdev; |
2702 | 2705 | ||
2703 | nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", | 2706 | nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", |
2704 | atomic_read(&nesvnic->netdev->refcnt)); | 2707 | netdev_refcnt_read(nesvnic->netdev)); |
2705 | 2708 | ||
2706 | if (nesqp->active_conn) { | 2709 | if (nesqp->active_conn) { |
2707 | 2710 | ||
@@ -2791,7 +2794,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2791 | atomic_inc(&cm_accepts); | 2794 | atomic_inc(&cm_accepts); |
2792 | 2795 | ||
2793 | nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", | 2796 | nes_debug(NES_DBG_CM, "netdev refcnt = %u.\n", |
2794 | atomic_read(&nesvnic->netdev->refcnt)); | 2797 | netdev_refcnt_read(nesvnic->netdev)); |
2795 | 2798 | ||
2796 | /* allocate the ietf frame and space for private data */ | 2799 | /* allocate the ietf frame and space for private data */ |
2797 | nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, | 2800 | nesqp->ietf_frame = pci_alloc_consistent(nesdev->pcidev, |
@@ -2963,7 +2966,7 @@ int nes_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | |||
2963 | nes_add_ref(&nesqp->ibqp); | 2966 | nes_add_ref(&nesqp->ibqp); |
2964 | 2967 | ||
2965 | cm_event.event = IW_CM_EVENT_ESTABLISHED; | 2968 | cm_event.event = IW_CM_EVENT_ESTABLISHED; |
2966 | cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; | 2969 | cm_event.status = 0; |
2967 | cm_event.provider_data = (void *)nesqp; | 2970 | cm_event.provider_data = (void *)nesqp; |
2968 | cm_event.local_addr = cm_id->local_addr; | 2971 | cm_event.local_addr = cm_id->local_addr; |
2969 | cm_event.remote_addr = cm_id->remote_addr; | 2972 | cm_event.remote_addr = cm_id->remote_addr; |
@@ -3374,7 +3377,7 @@ static void cm_event_connected(struct nes_cm_event *event) | |||
3374 | 3377 | ||
3375 | /* notify OF layer we successfully created the requested connection */ | 3378 | /* notify OF layer we successfully created the requested connection */ |
3376 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; | 3379 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; |
3377 | cm_event.status = IW_CM_EVENT_STATUS_ACCEPTED; | 3380 | cm_event.status = 0; |
3378 | cm_event.provider_data = cm_id->provider_data; | 3381 | cm_event.provider_data = cm_id->provider_data; |
3379 | cm_event.local_addr.sin_family = AF_INET; | 3382 | cm_event.local_addr.sin_family = AF_INET; |
3380 | cm_event.local_addr.sin_port = cm_id->local_addr.sin_port; | 3383 | cm_event.local_addr.sin_port = cm_id->local_addr.sin_port; |
@@ -3481,7 +3484,7 @@ static void cm_event_reset(struct nes_cm_event *event) | |||
3481 | nesqp->cm_id = NULL; | 3484 | nesqp->cm_id = NULL; |
3482 | /* cm_id->provider_data = NULL; */ | 3485 | /* cm_id->provider_data = NULL; */ |
3483 | cm_event.event = IW_CM_EVENT_DISCONNECT; | 3486 | cm_event.event = IW_CM_EVENT_DISCONNECT; |
3484 | cm_event.status = IW_CM_EVENT_STATUS_RESET; | 3487 | cm_event.status = -ECONNRESET; |
3485 | cm_event.provider_data = cm_id->provider_data; | 3488 | cm_event.provider_data = cm_id->provider_data; |
3486 | cm_event.local_addr = cm_id->local_addr; | 3489 | cm_event.local_addr = cm_id->local_addr; |
3487 | cm_event.remote_addr = cm_id->remote_addr; | 3490 | cm_event.remote_addr = cm_id->remote_addr; |
@@ -3492,7 +3495,7 @@ static void cm_event_reset(struct nes_cm_event *event) | |||
3492 | ret = cm_id->event_handler(cm_id, &cm_event); | 3495 | ret = cm_id->event_handler(cm_id, &cm_event); |
3493 | atomic_inc(&cm_closes); | 3496 | atomic_inc(&cm_closes); |
3494 | cm_event.event = IW_CM_EVENT_CLOSE; | 3497 | cm_event.event = IW_CM_EVENT_CLOSE; |
3495 | cm_event.status = IW_CM_EVENT_STATUS_OK; | 3498 | cm_event.status = 0; |
3496 | cm_event.provider_data = cm_id->provider_data; | 3499 | cm_event.provider_data = cm_id->provider_data; |
3497 | cm_event.local_addr = cm_id->local_addr; | 3500 | cm_event.local_addr = cm_id->local_addr; |
3498 | cm_event.remote_addr = cm_id->remote_addr; | 3501 | cm_event.remote_addr = cm_id->remote_addr; |
@@ -3531,7 +3534,7 @@ static void cm_event_mpa_req(struct nes_cm_event *event) | |||
3531 | cm_node, cm_id, jiffies); | 3534 | cm_node, cm_id, jiffies); |
3532 | 3535 | ||
3533 | cm_event.event = IW_CM_EVENT_CONNECT_REQUEST; | 3536 | cm_event.event = IW_CM_EVENT_CONNECT_REQUEST; |
3534 | cm_event.status = IW_CM_EVENT_STATUS_OK; | 3537 | cm_event.status = 0; |
3535 | cm_event.provider_data = (void *)cm_node; | 3538 | cm_event.provider_data = (void *)cm_node; |
3536 | 3539 | ||
3537 | cm_event.local_addr.sin_family = AF_INET; | 3540 | cm_event.local_addr.sin_family = AF_INET; |
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 1980a461c499..96fa9a4cafdf 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -80,7 +80,7 @@ static void nes_terminate_start_timer(struct nes_qp *nesqp); | |||
80 | 80 | ||
81 | #ifdef CONFIG_INFINIBAND_NES_DEBUG | 81 | #ifdef CONFIG_INFINIBAND_NES_DEBUG |
82 | static unsigned char *nes_iwarp_state_str[] = { | 82 | static unsigned char *nes_iwarp_state_str[] = { |
83 | "Non-Existant", | 83 | "Non-Existent", |
84 | "Idle", | 84 | "Idle", |
85 | "RTS", | 85 | "RTS", |
86 | "Closing", | 86 | "Closing", |
@@ -91,7 +91,7 @@ static unsigned char *nes_iwarp_state_str[] = { | |||
91 | }; | 91 | }; |
92 | 92 | ||
93 | static unsigned char *nes_tcp_state_str[] = { | 93 | static unsigned char *nes_tcp_state_str[] = { |
94 | "Non-Existant", | 94 | "Non-Existent", |
95 | "Closed", | 95 | "Closed", |
96 | "Listen", | 96 | "Listen", |
97 | "SYN Sent", | 97 | "SYN Sent", |
@@ -2608,6 +2608,15 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2608 | netif_start_queue(nesvnic->netdev); | 2608 | netif_start_queue(nesvnic->netdev); |
2609 | nesvnic->linkup = 1; | 2609 | nesvnic->linkup = 1; |
2610 | netif_carrier_on(nesvnic->netdev); | 2610 | netif_carrier_on(nesvnic->netdev); |
2611 | |||
2612 | spin_lock(&nesvnic->port_ibevent_lock); | ||
2613 | if (nesvnic->of_device_registered) { | ||
2614 | if (nesdev->iw_status == 0) { | ||
2615 | nesdev->iw_status = 1; | ||
2616 | nes_port_ibevent(nesvnic); | ||
2617 | } | ||
2618 | } | ||
2619 | spin_unlock(&nesvnic->port_ibevent_lock); | ||
2611 | } | 2620 | } |
2612 | } | 2621 | } |
2613 | } else { | 2622 | } else { |
@@ -2633,9 +2642,25 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2633 | netif_stop_queue(nesvnic->netdev); | 2642 | netif_stop_queue(nesvnic->netdev); |
2634 | nesvnic->linkup = 0; | 2643 | nesvnic->linkup = 0; |
2635 | netif_carrier_off(nesvnic->netdev); | 2644 | netif_carrier_off(nesvnic->netdev); |
2645 | |||
2646 | spin_lock(&nesvnic->port_ibevent_lock); | ||
2647 | if (nesvnic->of_device_registered) { | ||
2648 | if (nesdev->iw_status == 1) { | ||
2649 | nesdev->iw_status = 0; | ||
2650 | nes_port_ibevent(nesvnic); | ||
2651 | } | ||
2652 | } | ||
2653 | spin_unlock(&nesvnic->port_ibevent_lock); | ||
2636 | } | 2654 | } |
2637 | } | 2655 | } |
2638 | } | 2656 | } |
2657 | if (nesadapter->phy_type[mac_index] == NES_PHY_TYPE_SFP_D) { | ||
2658 | if (nesdev->link_recheck) | ||
2659 | cancel_delayed_work(&nesdev->work); | ||
2660 | nesdev->link_recheck = 1; | ||
2661 | schedule_delayed_work(&nesdev->work, | ||
2662 | NES_LINK_RECHECK_DELAY); | ||
2663 | } | ||
2639 | } | 2664 | } |
2640 | 2665 | ||
2641 | spin_unlock_irqrestore(&nesadapter->phy_lock, flags); | 2666 | spin_unlock_irqrestore(&nesadapter->phy_lock, flags); |
@@ -2643,6 +2668,84 @@ static void nes_process_mac_intr(struct nes_device *nesdev, u32 mac_number) | |||
2643 | nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE; | 2668 | nesadapter->mac_sw_state[mac_number] = NES_MAC_SW_IDLE; |
2644 | } | 2669 | } |
2645 | 2670 | ||
2671 | void nes_recheck_link_status(struct work_struct *work) | ||
2672 | { | ||
2673 | unsigned long flags; | ||
2674 | struct nes_device *nesdev = container_of(work, struct nes_device, work.work); | ||
2675 | struct nes_adapter *nesadapter = nesdev->nesadapter; | ||
2676 | struct nes_vnic *nesvnic; | ||
2677 | u32 mac_index = nesdev->mac_index; | ||
2678 | u16 phy_data; | ||
2679 | u16 temp_phy_data; | ||
2680 | |||
2681 | spin_lock_irqsave(&nesadapter->phy_lock, flags); | ||
2682 | |||
2683 | /* check link status */ | ||
2684 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 1, 0x9003); | ||
2685 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2686 | |||
2687 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021); | ||
2688 | nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2689 | nes_read_10G_phy_reg(nesdev, nesadapter->phy_index[mac_index], 3, 0x0021); | ||
2690 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
2691 | |||
2692 | phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0; | ||
2693 | |||
2694 | nes_debug(NES_DBG_PHY, "%s: Phy data = 0x%04X, link was %s.\n", | ||
2695 | __func__, phy_data, | ||
2696 | nesadapter->mac_link_down[mac_index] ? "DOWN" : "UP"); | ||
2697 | |||
2698 | if (phy_data & 0x0004) { | ||
2699 | nesadapter->mac_link_down[mac_index] = 0; | ||
2700 | list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { | ||
2701 | if (nesvnic->linkup == 0) { | ||
2702 | printk(PFX "The Link is now up for port %s, netdev %p.\n", | ||
2703 | nesvnic->netdev->name, nesvnic->netdev); | ||
2704 | if (netif_queue_stopped(nesvnic->netdev)) | ||
2705 | netif_start_queue(nesvnic->netdev); | ||
2706 | nesvnic->linkup = 1; | ||
2707 | netif_carrier_on(nesvnic->netdev); | ||
2708 | |||
2709 | spin_lock(&nesvnic->port_ibevent_lock); | ||
2710 | if (nesvnic->of_device_registered) { | ||
2711 | if (nesdev->iw_status == 0) { | ||
2712 | nesdev->iw_status = 1; | ||
2713 | nes_port_ibevent(nesvnic); | ||
2714 | } | ||
2715 | } | ||
2716 | spin_unlock(&nesvnic->port_ibevent_lock); | ||
2717 | } | ||
2718 | } | ||
2719 | |||
2720 | } else { | ||
2721 | nesadapter->mac_link_down[mac_index] = 1; | ||
2722 | list_for_each_entry(nesvnic, &nesadapter->nesvnic_list[mac_index], list) { | ||
2723 | if (nesvnic->linkup == 1) { | ||
2724 | printk(PFX "The Link is now down for port %s, netdev %p.\n", | ||
2725 | nesvnic->netdev->name, nesvnic->netdev); | ||
2726 | if (!(netif_queue_stopped(nesvnic->netdev))) | ||
2727 | netif_stop_queue(nesvnic->netdev); | ||
2728 | nesvnic->linkup = 0; | ||
2729 | netif_carrier_off(nesvnic->netdev); | ||
2730 | |||
2731 | spin_lock(&nesvnic->port_ibevent_lock); | ||
2732 | if (nesvnic->of_device_registered) { | ||
2733 | if (nesdev->iw_status == 1) { | ||
2734 | nesdev->iw_status = 0; | ||
2735 | nes_port_ibevent(nesvnic); | ||
2736 | } | ||
2737 | } | ||
2738 | spin_unlock(&nesvnic->port_ibevent_lock); | ||
2739 | } | ||
2740 | } | ||
2741 | } | ||
2742 | if (nesdev->link_recheck++ < NES_LINK_RECHECK_MAX) | ||
2743 | schedule_delayed_work(&nesdev->work, NES_LINK_RECHECK_DELAY); | ||
2744 | else | ||
2745 | nesdev->link_recheck = 0; | ||
2746 | |||
2747 | spin_unlock_irqrestore(&nesadapter->phy_lock, flags); | ||
2748 | } | ||
2646 | 2749 | ||
2647 | 2750 | ||
2648 | static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | 2751 | static void nes_nic_napi_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) |
@@ -2782,9 +2885,8 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2782 | if ((cqe_errv & | 2885 | if ((cqe_errv & |
2783 | (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR | | 2886 | (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_TCPUDP_CSUM_ERR | |
2784 | NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) { | 2887 | NES_NIC_ERRV_BITS_IPH_ERR | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) { |
2785 | if (nesvnic->rx_checksum_disabled == 0) { | 2888 | if (nesvnic->netdev->features & NETIF_F_RXCSUM) |
2786 | rx_skb->ip_summed = CHECKSUM_UNNECESSARY; | 2889 | rx_skb->ip_summed = CHECKSUM_UNNECESSARY; |
2787 | } | ||
2788 | } else | 2890 | } else |
2789 | nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet." | 2891 | nes_debug(NES_DBG_CQ, "%s: unsuccessfully checksummed TCP or UDP packet." |
2790 | " errv = 0x%X, pkt_type = 0x%X.\n", | 2892 | " errv = 0x%X, pkt_type = 0x%X.\n", |
@@ -2794,7 +2896,7 @@ void nes_nic_ce_handler(struct nes_device *nesdev, struct nes_hw_nic_cq *cq) | |||
2794 | if ((cqe_errv & | 2896 | if ((cqe_errv & |
2795 | (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR | | 2897 | (NES_NIC_ERRV_BITS_IPV4_CSUM_ERR | NES_NIC_ERRV_BITS_IPH_ERR | |
2796 | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) { | 2898 | NES_NIC_ERRV_BITS_WQE_OVERRUN)) == 0) { |
2797 | if (nesvnic->rx_checksum_disabled == 0) { | 2899 | if (nesvnic->netdev->features & NETIF_F_RXCSUM) { |
2798 | rx_skb->ip_summed = CHECKSUM_UNNECESSARY; | 2900 | rx_skb->ip_summed = CHECKSUM_UNNECESSARY; |
2799 | /* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n", | 2901 | /* nes_debug(NES_DBG_CQ, "%s: Reporting successfully checksummed IPv4 packet.\n", |
2800 | nesvnic->netdev->name); */ | 2902 | nesvnic->netdev->name); */ |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 1204c3432b63..91594116f947 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -1193,6 +1193,8 @@ struct nes_listener { | |||
1193 | 1193 | ||
1194 | struct nes_ib_device; | 1194 | struct nes_ib_device; |
1195 | 1195 | ||
1196 | #define NES_EVENT_DELAY msecs_to_jiffies(100) | ||
1197 | |||
1196 | struct nes_vnic { | 1198 | struct nes_vnic { |
1197 | struct nes_ib_device *nesibdev; | 1199 | struct nes_ib_device *nesibdev; |
1198 | u64 sq_full; | 1200 | u64 sq_full; |
@@ -1243,10 +1245,13 @@ struct nes_vnic { | |||
1243 | u8 next_qp_nic_index; | 1245 | u8 next_qp_nic_index; |
1244 | u8 of_device_registered; | 1246 | u8 of_device_registered; |
1245 | u8 rdma_enabled; | 1247 | u8 rdma_enabled; |
1246 | u8 rx_checksum_disabled; | ||
1247 | u32 lro_max_aggr; | 1248 | u32 lro_max_aggr; |
1248 | struct net_lro_mgr lro_mgr; | 1249 | struct net_lro_mgr lro_mgr; |
1249 | struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS]; | 1250 | struct net_lro_desc lro_desc[NES_MAX_LRO_DESCRIPTORS]; |
1251 | struct timer_list event_timer; | ||
1252 | enum ib_event_type delayed_event; | ||
1253 | enum ib_event_type last_dispatched_event; | ||
1254 | spinlock_t port_ibevent_lock; | ||
1250 | }; | 1255 | }; |
1251 | 1256 | ||
1252 | struct nes_ib_device { | 1257 | struct nes_ib_device { |
@@ -1348,6 +1353,10 @@ struct nes_terminate_hdr { | |||
1348 | #define BAD_FRAME_OFFSET 64 | 1353 | #define BAD_FRAME_OFFSET 64 |
1349 | #define CQE_MAJOR_DRV 0x8000 | 1354 | #define CQE_MAJOR_DRV 0x8000 |
1350 | 1355 | ||
1356 | /* Used for link status recheck after interrupt processing */ | ||
1357 | #define NES_LINK_RECHECK_DELAY msecs_to_jiffies(50) | ||
1358 | #define NES_LINK_RECHECK_MAX 60 | ||
1359 | |||
1351 | #define nes_vlan_rx vlan_hwaccel_receive_skb | 1360 | #define nes_vlan_rx vlan_hwaccel_receive_skb |
1352 | #define nes_netif_rx netif_receive_skb | 1361 | #define nes_netif_rx netif_receive_skb |
1353 | 1362 | ||
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 10560c796fd6..d3a1c41cfd27 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -144,6 +144,7 @@ static int nes_netdev_open(struct net_device *netdev) | |||
144 | u32 nic_active_bit; | 144 | u32 nic_active_bit; |
145 | u32 nic_active; | 145 | u32 nic_active; |
146 | struct list_head *list_pos, *list_temp; | 146 | struct list_head *list_pos, *list_temp; |
147 | unsigned long flags; | ||
147 | 148 | ||
148 | assert(nesdev != NULL); | 149 | assert(nesdev != NULL); |
149 | 150 | ||
@@ -233,18 +234,36 @@ static int nes_netdev_open(struct net_device *netdev) | |||
233 | first_nesvnic = nesvnic; | 234 | first_nesvnic = nesvnic; |
234 | } | 235 | } |
235 | 236 | ||
236 | if (nesvnic->of_device_registered) { | ||
237 | nesdev->iw_status = 1; | ||
238 | nesdev->nesadapter->send_term_ok = 1; | ||
239 | nes_port_ibevent(nesvnic); | ||
240 | } | ||
241 | |||
242 | if (first_nesvnic->linkup) { | 237 | if (first_nesvnic->linkup) { |
243 | /* Enable network packets */ | 238 | /* Enable network packets */ |
244 | nesvnic->linkup = 1; | 239 | nesvnic->linkup = 1; |
245 | netif_start_queue(netdev); | 240 | netif_start_queue(netdev); |
246 | netif_carrier_on(netdev); | 241 | netif_carrier_on(netdev); |
247 | } | 242 | } |
243 | |||
244 | spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); | ||
245 | if (nesdev->nesadapter->phy_type[nesdev->mac_index] == NES_PHY_TYPE_SFP_D) { | ||
246 | if (nesdev->link_recheck) | ||
247 | cancel_delayed_work(&nesdev->work); | ||
248 | nesdev->link_recheck = 1; | ||
249 | schedule_delayed_work(&nesdev->work, NES_LINK_RECHECK_DELAY); | ||
250 | } | ||
251 | spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); | ||
252 | |||
253 | spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags); | ||
254 | if (nesvnic->of_device_registered) { | ||
255 | nesdev->nesadapter->send_term_ok = 1; | ||
256 | if (nesvnic->linkup == 1) { | ||
257 | if (nesdev->iw_status == 0) { | ||
258 | nesdev->iw_status = 1; | ||
259 | nes_port_ibevent(nesvnic); | ||
260 | } | ||
261 | } else { | ||
262 | nesdev->iw_status = 0; | ||
263 | } | ||
264 | } | ||
265 | spin_unlock_irqrestore(&nesvnic->port_ibevent_lock, flags); | ||
266 | |||
248 | napi_enable(&nesvnic->napi); | 267 | napi_enable(&nesvnic->napi); |
249 | nesvnic->netdev_open = 1; | 268 | nesvnic->netdev_open = 1; |
250 | 269 | ||
@@ -263,6 +282,7 @@ static int nes_netdev_stop(struct net_device *netdev) | |||
263 | u32 nic_active; | 282 | u32 nic_active; |
264 | struct nes_vnic *first_nesvnic = NULL; | 283 | struct nes_vnic *first_nesvnic = NULL; |
265 | struct list_head *list_pos, *list_temp; | 284 | struct list_head *list_pos, *list_temp; |
285 | unsigned long flags; | ||
266 | 286 | ||
267 | nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n", | 287 | nes_debug(NES_DBG_SHUTDOWN, "nesvnic=%p, nesdev=%p, netdev=%p %s\n", |
268 | nesvnic, nesdev, netdev, netdev->name); | 288 | nesvnic, nesdev, netdev, netdev->name); |
@@ -271,6 +291,7 @@ static int nes_netdev_stop(struct net_device *netdev) | |||
271 | 291 | ||
272 | if (netif_msg_ifdown(nesvnic)) | 292 | if (netif_msg_ifdown(nesvnic)) |
273 | printk(KERN_INFO PFX "%s: disabling interface\n", netdev->name); | 293 | printk(KERN_INFO PFX "%s: disabling interface\n", netdev->name); |
294 | netif_carrier_off(netdev); | ||
274 | 295 | ||
275 | /* Disable network packets */ | 296 | /* Disable network packets */ |
276 | napi_disable(&nesvnic->napi); | 297 | napi_disable(&nesvnic->napi); |
@@ -314,12 +335,17 @@ static int nes_netdev_stop(struct net_device *netdev) | |||
314 | nic_active &= nic_active_mask; | 335 | nic_active &= nic_active_mask; |
315 | nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); | 336 | nes_write_indexed(nesdev, NES_IDX_NIC_BROADCAST_ON, nic_active); |
316 | 337 | ||
317 | 338 | spin_lock_irqsave(&nesvnic->port_ibevent_lock, flags); | |
318 | if (nesvnic->of_device_registered) { | 339 | if (nesvnic->of_device_registered) { |
319 | nesdev->nesadapter->send_term_ok = 0; | 340 | nesdev->nesadapter->send_term_ok = 0; |
320 | nesdev->iw_status = 0; | 341 | nesdev->iw_status = 0; |
321 | nes_port_ibevent(nesvnic); | 342 | if (nesvnic->linkup == 1) |
343 | nes_port_ibevent(nesvnic); | ||
322 | } | 344 | } |
345 | del_timer_sync(&nesvnic->event_timer); | ||
346 | nesvnic->event_timer.function = NULL; | ||
347 | spin_unlock_irqrestore(&nesvnic->port_ibevent_lock, flags); | ||
348 | |||
323 | nes_destroy_nic_qp(nesvnic); | 349 | nes_destroy_nic_qp(nesvnic); |
324 | 350 | ||
325 | nesvnic->netdev_open = 0; | 351 | nesvnic->netdev_open = 0; |
@@ -876,7 +902,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
876 | nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); | 902 | nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); |
877 | } | 903 | } |
878 | 904 | ||
879 | nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", | 905 | nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscuous = %d, All Multicast = %d.\n", |
880 | mc_count, !!(netdev->flags & IFF_PROMISC), | 906 | mc_count, !!(netdev->flags & IFF_PROMISC), |
881 | !!(netdev->flags & IFF_ALLMULTI)); | 907 | !!(netdev->flags & IFF_ALLMULTI)); |
882 | if (!mc_all_on) { | 908 | if (!mc_all_on) { |
@@ -907,8 +933,8 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
907 | nesvnic->nic_index && | 933 | nesvnic->nic_index && |
908 | mc_index < max_pft_entries_avaiable) { | 934 | mc_index < max_pft_entries_avaiable) { |
909 | nes_debug(NES_DBG_NIC_RX, | 935 | nes_debug(NES_DBG_NIC_RX, |
910 | "mc_index=%d skipping nic_index=%d,\ | 936 | "mc_index=%d skipping nic_index=%d, " |
911 | used for=%d \n", mc_index, | 937 | "used for=%d \n", mc_index, |
912 | nesvnic->nic_index, | 938 | nesvnic->nic_index, |
913 | nesadapter->pft_mcast_map[mc_index]); | 939 | nesadapter->pft_mcast_map[mc_index]); |
914 | mc_index++; | 940 | mc_index++; |
@@ -1067,34 +1093,6 @@ static const char nes_ethtool_stringset[][ETH_GSTRING_LEN] = { | |||
1067 | }; | 1093 | }; |
1068 | #define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset) | 1094 | #define NES_ETHTOOL_STAT_COUNT ARRAY_SIZE(nes_ethtool_stringset) |
1069 | 1095 | ||
1070 | /** | ||
1071 | * nes_netdev_get_rx_csum | ||
1072 | */ | ||
1073 | static u32 nes_netdev_get_rx_csum (struct net_device *netdev) | ||
1074 | { | ||
1075 | struct nes_vnic *nesvnic = netdev_priv(netdev); | ||
1076 | |||
1077 | if (nesvnic->rx_checksum_disabled) | ||
1078 | return 0; | ||
1079 | else | ||
1080 | return 1; | ||
1081 | } | ||
1082 | |||
1083 | |||
1084 | /** | ||
1085 | * nes_netdev_set_rc_csum | ||
1086 | */ | ||
1087 | static int nes_netdev_set_rx_csum(struct net_device *netdev, u32 enable) | ||
1088 | { | ||
1089 | struct nes_vnic *nesvnic = netdev_priv(netdev); | ||
1090 | |||
1091 | if (enable) | ||
1092 | nesvnic->rx_checksum_disabled = 0; | ||
1093 | else | ||
1094 | nesvnic->rx_checksum_disabled = 1; | ||
1095 | return 0; | ||
1096 | } | ||
1097 | |||
1098 | 1096 | ||
1099 | /** | 1097 | /** |
1100 | * nes_netdev_get_sset_count | 1098 | * nes_netdev_get_sset_count |
@@ -1495,7 +1493,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd | |||
1495 | et_cmd->maxrxpkt = 511; | 1493 | et_cmd->maxrxpkt = 511; |
1496 | 1494 | ||
1497 | if (nesadapter->OneG_Mode) { | 1495 | if (nesadapter->OneG_Mode) { |
1498 | et_cmd->speed = SPEED_1000; | 1496 | ethtool_cmd_speed_set(et_cmd, SPEED_1000); |
1499 | if (phy_type == NES_PHY_TYPE_PUMA_1G) { | 1497 | if (phy_type == NES_PHY_TYPE_PUMA_1G) { |
1500 | et_cmd->supported = SUPPORTED_1000baseT_Full; | 1498 | et_cmd->supported = SUPPORTED_1000baseT_Full; |
1501 | et_cmd->advertising = ADVERTISED_1000baseT_Full; | 1499 | et_cmd->advertising = ADVERTISED_1000baseT_Full; |
@@ -1534,7 +1532,7 @@ static int nes_netdev_get_settings(struct net_device *netdev, struct ethtool_cmd | |||
1534 | et_cmd->advertising = ADVERTISED_10000baseT_Full; | 1532 | et_cmd->advertising = ADVERTISED_10000baseT_Full; |
1535 | et_cmd->phy_address = mac_index; | 1533 | et_cmd->phy_address = mac_index; |
1536 | } | 1534 | } |
1537 | et_cmd->speed = SPEED_10000; | 1535 | ethtool_cmd_speed_set(et_cmd, SPEED_10000); |
1538 | et_cmd->autoneg = AUTONEG_DISABLE; | 1536 | et_cmd->autoneg = AUTONEG_DISABLE; |
1539 | return 0; | 1537 | return 0; |
1540 | } | 1538 | } |
@@ -1572,19 +1570,10 @@ static int nes_netdev_set_settings(struct net_device *netdev, struct ethtool_cmd | |||
1572 | } | 1570 | } |
1573 | 1571 | ||
1574 | 1572 | ||
1575 | static int nes_netdev_set_flags(struct net_device *netdev, u32 flags) | ||
1576 | { | ||
1577 | return ethtool_op_set_flags(netdev, flags, ETH_FLAG_LRO); | ||
1578 | } | ||
1579 | |||
1580 | |||
1581 | static const struct ethtool_ops nes_ethtool_ops = { | 1573 | static const struct ethtool_ops nes_ethtool_ops = { |
1582 | .get_link = ethtool_op_get_link, | 1574 | .get_link = ethtool_op_get_link, |
1583 | .get_settings = nes_netdev_get_settings, | 1575 | .get_settings = nes_netdev_get_settings, |
1584 | .set_settings = nes_netdev_set_settings, | 1576 | .set_settings = nes_netdev_set_settings, |
1585 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
1586 | .get_rx_csum = nes_netdev_get_rx_csum, | ||
1587 | .get_sg = ethtool_op_get_sg, | ||
1588 | .get_strings = nes_netdev_get_strings, | 1577 | .get_strings = nes_netdev_get_strings, |
1589 | .get_sset_count = nes_netdev_get_sset_count, | 1578 | .get_sset_count = nes_netdev_get_sset_count, |
1590 | .get_ethtool_stats = nes_netdev_get_ethtool_stats, | 1579 | .get_ethtool_stats = nes_netdev_get_ethtool_stats, |
@@ -1593,13 +1582,6 @@ static const struct ethtool_ops nes_ethtool_ops = { | |||
1593 | .set_coalesce = nes_netdev_set_coalesce, | 1582 | .set_coalesce = nes_netdev_set_coalesce, |
1594 | .get_pauseparam = nes_netdev_get_pauseparam, | 1583 | .get_pauseparam = nes_netdev_get_pauseparam, |
1595 | .set_pauseparam = nes_netdev_set_pauseparam, | 1584 | .set_pauseparam = nes_netdev_set_pauseparam, |
1596 | .set_tx_csum = ethtool_op_set_tx_csum, | ||
1597 | .set_rx_csum = nes_netdev_set_rx_csum, | ||
1598 | .set_sg = ethtool_op_set_sg, | ||
1599 | .get_tso = ethtool_op_get_tso, | ||
1600 | .set_tso = ethtool_op_set_tso, | ||
1601 | .get_flags = ethtool_op_get_flags, | ||
1602 | .set_flags = nes_netdev_set_flags, | ||
1603 | }; | 1585 | }; |
1604 | 1586 | ||
1605 | 1587 | ||
@@ -1701,12 +1683,11 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1701 | netdev->dev_addr[5] = (u8)u64temp; | 1683 | netdev->dev_addr[5] = (u8)u64temp; |
1702 | memcpy(netdev->perm_addr, netdev->dev_addr, 6); | 1684 | memcpy(netdev->perm_addr, netdev->dev_addr, 6); |
1703 | 1685 | ||
1704 | if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) { | 1686 | netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_IP_CSUM; |
1705 | netdev->features |= NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; | 1687 | if ((nesvnic->logical_port < 2) || (nesdev->nesadapter->hw_rev != NE020_REV)) |
1706 | netdev->features |= NETIF_F_GSO | NETIF_F_TSO | NETIF_F_SG | NETIF_F_IP_CSUM; | 1688 | netdev->hw_features |= NETIF_F_TSO; |
1707 | } else { | 1689 | netdev->features |= netdev->hw_features; |
1708 | netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; | 1690 | netdev->hw_features |= NETIF_F_LRO; |
1709 | } | ||
1710 | 1691 | ||
1711 | nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d," | 1692 | nes_debug(NES_DBG_INIT, "nesvnic = %p, reported features = 0x%lX, QPid = %d," |
1712 | " nic_index = %d, logical_port = %d, mac_index = %d.\n", | 1693 | " nic_index = %d, logical_port = %d, mac_index = %d.\n", |
@@ -1749,7 +1730,10 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1749 | nesvnic->rdma_enabled = 0; | 1730 | nesvnic->rdma_enabled = 0; |
1750 | } | 1731 | } |
1751 | nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id; | 1732 | nesvnic->nic_cq.cq_number = nesvnic->nic.qp_id; |
1733 | init_timer(&nesvnic->event_timer); | ||
1734 | nesvnic->event_timer.function = NULL; | ||
1752 | spin_lock_init(&nesvnic->tx_lock); | 1735 | spin_lock_init(&nesvnic->tx_lock); |
1736 | spin_lock_init(&nesvnic->port_ibevent_lock); | ||
1753 | nesdev->netdev[nesdev->netdev_count] = netdev; | 1737 | nesdev->netdev[nesdev->netdev_count] = netdev; |
1754 | 1738 | ||
1755 | nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n", | 1739 | nes_debug(NES_DBG_INIT, "Adding nesvnic (%p) to the adapters nesvnic_list for MAC%d.\n", |
@@ -1762,8 +1746,11 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1762 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || | 1746 | (((PCI_FUNC(nesdev->pcidev->devfn) == 1) && (nesdev->mac_index == 2)) || |
1763 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { | 1747 | ((PCI_FUNC(nesdev->pcidev->devfn) == 2) && (nesdev->mac_index == 1)))))) { |
1764 | u32 u32temp; | 1748 | u32 u32temp; |
1765 | u32 link_mask; | 1749 | u32 link_mask = 0; |
1766 | u32 link_val; | 1750 | u32 link_val = 0; |
1751 | u16 temp_phy_data; | ||
1752 | u16 phy_data = 0; | ||
1753 | unsigned long flags; | ||
1767 | 1754 | ||
1768 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1755 | u32temp = nes_read_indexed(nesdev, NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1769 | (0x200 * (nesdev->mac_index & 1))); | 1756 | (0x200 * (nesdev->mac_index & 1))); |
@@ -1785,6 +1772,23 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1785 | link_val = 0x02020000; | 1772 | link_val = 0x02020000; |
1786 | } | 1773 | } |
1787 | break; | 1774 | break; |
1775 | case NES_PHY_TYPE_SFP_D: | ||
1776 | spin_lock_irqsave(&nesdev->nesadapter->phy_lock, flags); | ||
1777 | nes_read_10G_phy_reg(nesdev, | ||
1778 | nesdev->nesadapter->phy_index[nesdev->mac_index], | ||
1779 | 1, 0x9003); | ||
1780 | temp_phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1781 | nes_read_10G_phy_reg(nesdev, | ||
1782 | nesdev->nesadapter->phy_index[nesdev->mac_index], | ||
1783 | 3, 0x0021); | ||
1784 | nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1785 | nes_read_10G_phy_reg(nesdev, | ||
1786 | nesdev->nesadapter->phy_index[nesdev->mac_index], | ||
1787 | 3, 0x0021); | ||
1788 | phy_data = (u16)nes_read_indexed(nesdev, NES_IDX_MAC_MDIO_CONTROL); | ||
1789 | spin_unlock_irqrestore(&nesdev->nesadapter->phy_lock, flags); | ||
1790 | phy_data = (!temp_phy_data && (phy_data == 0x8000)) ? 0x4 : 0x0; | ||
1791 | break; | ||
1788 | default: | 1792 | default: |
1789 | link_mask = 0x0f1f0000; | 1793 | link_mask = 0x0f1f0000; |
1790 | link_val = 0x0f0f0000; | 1794 | link_val = 0x0f0f0000; |
@@ -1794,8 +1798,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1794 | u32temp = nes_read_indexed(nesdev, | 1798 | u32temp = nes_read_indexed(nesdev, |
1795 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + | 1799 | NES_IDX_PHY_PCS_CONTROL_STATUS0 + |
1796 | (0x200 * (nesdev->mac_index & 1))); | 1800 | (0x200 * (nesdev->mac_index & 1))); |
1797 | if ((u32temp & link_mask) == link_val) | 1801 | |
1798 | nesvnic->linkup = 1; | 1802 | if (phy_type == NES_PHY_TYPE_SFP_D) { |
1803 | if (phy_data & 0x0004) | ||
1804 | nesvnic->linkup = 1; | ||
1805 | } else { | ||
1806 | if ((u32temp & link_mask) == link_val) | ||
1807 | nesvnic->linkup = 1; | ||
1808 | } | ||
1799 | 1809 | ||
1800 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ | 1810 | /* clear the MAC interrupt status, assumes direct logical to physical mapping */ |
1801 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); | 1811 | u32temp = nes_read_indexed(nesdev, NES_IDX_MAC_INT_STATUS + (0x200 * nesdev->mac_index)); |
diff --git a/drivers/infiniband/hw/nes/nes_verbs.c b/drivers/infiniband/hw/nes/nes_verbs.c index 9046e6675686..95ca93ceedac 100644 --- a/drivers/infiniband/hw/nes/nes_verbs.c +++ b/drivers/infiniband/hw/nes/nes_verbs.c | |||
@@ -476,9 +476,9 @@ static struct ib_fast_reg_page_list *nes_alloc_fast_reg_page_list( | |||
476 | } | 476 | } |
477 | nes_debug(NES_DBG_MR, "nes_alloc_fast_reg_pbl: nes_frpl = %p, " | 477 | nes_debug(NES_DBG_MR, "nes_alloc_fast_reg_pbl: nes_frpl = %p, " |
478 | "ibfrpl = %p, ibfrpl.page_list = %p, pbl.kva = %p, " | 478 | "ibfrpl = %p, ibfrpl.page_list = %p, pbl.kva = %p, " |
479 | "pbl.paddr= %p\n", pnesfrpl, &pnesfrpl->ibfrpl, | 479 | "pbl.paddr = %llx\n", pnesfrpl, &pnesfrpl->ibfrpl, |
480 | pnesfrpl->ibfrpl.page_list, pnesfrpl->nes_wqe_pbl.kva, | 480 | pnesfrpl->ibfrpl.page_list, pnesfrpl->nes_wqe_pbl.kva, |
481 | (void *)pnesfrpl->nes_wqe_pbl.paddr); | 481 | (unsigned long long) pnesfrpl->nes_wqe_pbl.paddr); |
482 | 482 | ||
483 | return pifrpl; | 483 | return pifrpl; |
484 | } | 484 | } |
@@ -584,7 +584,9 @@ static int nes_query_port(struct ib_device *ibdev, u8 port, struct ib_port_attr | |||
584 | props->lmc = 0; | 584 | props->lmc = 0; |
585 | props->sm_lid = 0; | 585 | props->sm_lid = 0; |
586 | props->sm_sl = 0; | 586 | props->sm_sl = 0; |
587 | if (nesvnic->linkup) | 587 | if (netif_queue_stopped(netdev)) |
588 | props->state = IB_PORT_DOWN; | ||
589 | else if (nesvnic->linkup) | ||
588 | props->state = IB_PORT_ACTIVE; | 590 | props->state = IB_PORT_ACTIVE; |
589 | else | 591 | else |
590 | props->state = IB_PORT_DOWN; | 592 | props->state = IB_PORT_DOWN; |
@@ -785,7 +787,7 @@ static struct ib_pd *nes_alloc_pd(struct ib_device *ibdev, | |||
785 | 787 | ||
786 | nes_debug(NES_DBG_PD, "nesvnic=%p, netdev=%p %s, ibdev=%p, context=%p, netdev refcnt=%u\n", | 788 | nes_debug(NES_DBG_PD, "nesvnic=%p, netdev=%p %s, ibdev=%p, context=%p, netdev refcnt=%u\n", |
787 | nesvnic, nesdev->netdev[0], nesdev->netdev[0]->name, ibdev, context, | 789 | nesvnic, nesdev->netdev[0], nesdev->netdev[0]->name, ibdev, context, |
788 | atomic_read(&nesvnic->netdev->refcnt)); | 790 | netdev_refcnt_read(nesvnic->netdev)); |
789 | 791 | ||
790 | err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds, | 792 | err = nes_alloc_resource(nesadapter, nesadapter->allocated_pds, |
791 | nesadapter->max_pd, &pd_num, &nesadapter->next_pd); | 793 | nesadapter->max_pd, &pd_num, &nesadapter->next_pd); |
@@ -1416,7 +1418,7 @@ static struct ib_qp *nes_create_qp(struct ib_pd *ibpd, | |||
1416 | /* update the QP table */ | 1418 | /* update the QP table */ |
1417 | nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; | 1419 | nesdev->nesadapter->qp_table[nesqp->hwqp.qp_id-NES_FIRST_QPN] = nesqp; |
1418 | nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", | 1420 | nes_debug(NES_DBG_QP, "netdev refcnt=%u\n", |
1419 | atomic_read(&nesvnic->netdev->refcnt)); | 1421 | netdev_refcnt_read(nesvnic->netdev)); |
1420 | 1422 | ||
1421 | return &nesqp->ibqp; | 1423 | return &nesqp->ibqp; |
1422 | } | 1424 | } |
@@ -1482,7 +1484,7 @@ static int nes_destroy_qp(struct ib_qp *ibqp) | |||
1482 | (nesqp->ibqp_state == IB_QPS_RTR)) && (nesqp->cm_id)) { | 1484 | (nesqp->ibqp_state == IB_QPS_RTR)) && (nesqp->cm_id)) { |
1483 | cm_id = nesqp->cm_id; | 1485 | cm_id = nesqp->cm_id; |
1484 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; | 1486 | cm_event.event = IW_CM_EVENT_CONNECT_REPLY; |
1485 | cm_event.status = IW_CM_EVENT_STATUS_TIMEOUT; | 1487 | cm_event.status = -ETIMEDOUT; |
1486 | cm_event.local_addr = cm_id->local_addr; | 1488 | cm_event.local_addr = cm_id->local_addr; |
1487 | cm_event.remote_addr = cm_id->remote_addr; | 1489 | cm_event.remote_addr = cm_id->remote_addr; |
1488 | cm_event.private_data = NULL; | 1490 | cm_event.private_data = NULL; |
@@ -3483,13 +3485,13 @@ static int nes_post_send(struct ib_qp *ibqp, struct ib_send_wr *ib_wr, | |||
3483 | for (i = 0; i < ib_wr->wr.fast_reg.page_list_len; i++) | 3485 | for (i = 0; i < ib_wr->wr.fast_reg.page_list_len; i++) |
3484 | dst_page_list[i] = cpu_to_le64(src_page_list[i]); | 3486 | dst_page_list[i] = cpu_to_le64(src_page_list[i]); |
3485 | 3487 | ||
3486 | nes_debug(NES_DBG_IW_TX, "SQ_FMR: iova_start: %p, " | 3488 | nes_debug(NES_DBG_IW_TX, "SQ_FMR: iova_start: %llx, " |
3487 | "length: %d, rkey: %0x, pgl_paddr: %p, " | 3489 | "length: %d, rkey: %0x, pgl_paddr: %llx, " |
3488 | "page_list_len: %u, wqe_misc: %x\n", | 3490 | "page_list_len: %u, wqe_misc: %x\n", |
3489 | (void *)ib_wr->wr.fast_reg.iova_start, | 3491 | (unsigned long long) ib_wr->wr.fast_reg.iova_start, |
3490 | ib_wr->wr.fast_reg.length, | 3492 | ib_wr->wr.fast_reg.length, |
3491 | ib_wr->wr.fast_reg.rkey, | 3493 | ib_wr->wr.fast_reg.rkey, |
3492 | (void *)pnesfrpl->nes_wqe_pbl.paddr, | 3494 | (unsigned long long) pnesfrpl->nes_wqe_pbl.paddr, |
3493 | ib_wr->wr.fast_reg.page_list_len, | 3495 | ib_wr->wr.fast_reg.page_list_len, |
3494 | wqe_misc); | 3496 | wqe_misc); |
3495 | break; | 3497 | break; |
@@ -3934,6 +3936,30 @@ struct nes_ib_device *nes_init_ofa_device(struct net_device *netdev) | |||
3934 | return nesibdev; | 3936 | return nesibdev; |
3935 | } | 3937 | } |
3936 | 3938 | ||
3939 | |||
3940 | /** | ||
3941 | * nes_handle_delayed_event | ||
3942 | */ | ||
3943 | static void nes_handle_delayed_event(unsigned long data) | ||
3944 | { | ||
3945 | struct nes_vnic *nesvnic = (void *) data; | ||
3946 | |||
3947 | if (nesvnic->delayed_event != nesvnic->last_dispatched_event) { | ||
3948 | struct ib_event event; | ||
3949 | |||
3950 | event.device = &nesvnic->nesibdev->ibdev; | ||
3951 | if (!event.device) | ||
3952 | goto stop_timer; | ||
3953 | event.event = nesvnic->delayed_event; | ||
3954 | event.element.port_num = nesvnic->logical_port + 1; | ||
3955 | ib_dispatch_event(&event); | ||
3956 | } | ||
3957 | |||
3958 | stop_timer: | ||
3959 | nesvnic->event_timer.function = NULL; | ||
3960 | } | ||
3961 | |||
3962 | |||
3937 | void nes_port_ibevent(struct nes_vnic *nesvnic) | 3963 | void nes_port_ibevent(struct nes_vnic *nesvnic) |
3938 | { | 3964 | { |
3939 | struct nes_ib_device *nesibdev = nesvnic->nesibdev; | 3965 | struct nes_ib_device *nesibdev = nesvnic->nesibdev; |
@@ -3942,7 +3968,18 @@ void nes_port_ibevent(struct nes_vnic *nesvnic) | |||
3942 | event.device = &nesibdev->ibdev; | 3968 | event.device = &nesibdev->ibdev; |
3943 | event.element.port_num = nesvnic->logical_port + 1; | 3969 | event.element.port_num = nesvnic->logical_port + 1; |
3944 | event.event = nesdev->iw_status ? IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR; | 3970 | event.event = nesdev->iw_status ? IB_EVENT_PORT_ACTIVE : IB_EVENT_PORT_ERR; |
3945 | ib_dispatch_event(&event); | 3971 | |
3972 | if (!nesvnic->event_timer.function) { | ||
3973 | ib_dispatch_event(&event); | ||
3974 | nesvnic->last_dispatched_event = event.event; | ||
3975 | nesvnic->event_timer.function = nes_handle_delayed_event; | ||
3976 | nesvnic->event_timer.data = (unsigned long) nesvnic; | ||
3977 | nesvnic->event_timer.expires = jiffies + NES_EVENT_DELAY; | ||
3978 | add_timer(&nesvnic->event_timer); | ||
3979 | } else { | ||
3980 | mod_timer(&nesvnic->event_timer, jiffies + NES_EVENT_DELAY); | ||
3981 | } | ||
3982 | nesvnic->delayed_event = event.event; | ||
3946 | } | 3983 | } |
3947 | 3984 | ||
3948 | 3985 | ||