*  '-1' on failure
  */
 
-static int init_tti(struct s2io_nic *nic, int link)
+static int init_tti(struct s2io_nic *nic, int link, bool may_sleep)
 {
        struct XENA_dev_config __iomem *bar0 = nic->bar0;
        register u64 val64 = 0;
 
                if (wait_for_cmd_complete(&bar0->tti_command_mem,
                                          TTI_CMD_MEM_STROBE_NEW_CMD,
-                                         S2IO_BIT_RESET) != SUCCESS)
+                                         S2IO_BIT_RESET, may_sleep) != SUCCESS)
                        return FAILURE;
        }
 
         */
 
        /* Initialize TTI */
-       if (SUCCESS != init_tti(nic, nic->last_link_state))
+       if (SUCCESS != init_tti(nic, nic->last_link_state, true))
                return -ENODEV;
 
        /* RTI Initialization */
  */
 
 static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit,
-                                int bit_state)
+                                int bit_state, bool may_sleep)
 {
        int ret = FAILURE, cnt = 0, delay = 1;
        u64 val64;
                        }
                }
 
-               if (in_interrupt())
+               if (!may_sleep)
                        mdelay(delay);
                else
                        msleep(delay);
  *  Return value:
  *  void.
  */
-
-static void s2io_set_multicast(struct net_device *dev)
+static void s2io_set_multicast(struct net_device *dev, bool may_sleep)
 {
        int i, j, prev_cnt;
        struct netdev_hw_addr *ha;
                /* Wait till command completes */
                wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                                      RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-                                     S2IO_BIT_RESET);
+                                     S2IO_BIT_RESET, may_sleep);
 
                sp->m_cast_flg = 1;
                sp->all_multi_pos = config->max_mc_addr - 1;
                /* Wait till command completes */
                wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                                      RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-                                     S2IO_BIT_RESET);
+                                     S2IO_BIT_RESET, may_sleep);
 
                sp->m_cast_flg = 0;
                sp->all_multi_pos = 0;
                        /* Wait for command completes */
                        if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                                                  RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-                                                 S2IO_BIT_RESET)) {
+                                                 S2IO_BIT_RESET, may_sleep)) {
                                DBG_PRINT(ERR_DBG,
                                          "%s: Adding Multicasts failed\n",
                                          dev->name);
                        /* Wait for command completes */
                        if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                                                  RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-                                                 S2IO_BIT_RESET)) {
+                                                 S2IO_BIT_RESET, may_sleep)) {
                                DBG_PRINT(ERR_DBG,
                                          "%s: Adding Multicasts failed\n",
                                          dev->name);
        }
 }
 
+/* NDO wrapper for s2io_set_multicast */
+static void s2io_ndo_set_multicast(struct net_device *dev)
+{
+       s2io_set_multicast(dev, false);
+}
+
 /* read from CAM unicast & multicast addresses and store it in
  * def_mac_addr structure
  */
        /* Wait till command completes */
        if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                                  RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-                                 S2IO_BIT_RESET)) {
+                                 S2IO_BIT_RESET, true)) {
                DBG_PRINT(INFO_DBG, "do_s2io_add_mac failed\n");
                return FAILURE;
        }
        /* Wait till command completes */
        if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                                  RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-                                 S2IO_BIT_RESET)) {
+                                 S2IO_BIT_RESET, true)) {
                DBG_PRINT(INFO_DBG, "do_s2io_read_unicast_mc failed\n");
                return FAILURE;
        }
        }
 
        /* Setting its receive mode */
-       s2io_set_multicast(dev);
+       s2io_set_multicast(dev, true);
 
        if (dev->features & NETIF_F_LRO) {
                /* Initialize max aggregatable pkts per session based on MTU */
        struct swStat *swstats = &sp->mac_control.stats_info->sw_stat;
 
        if (link != sp->last_link_state) {
-               init_tti(sp, link);
+               init_tti(sp, link, false);
                if (link == LINK_DOWN) {
                        DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name);
                        s2io_stop_all_tx_queue(sp);
 
        return wait_for_cmd_complete(&bar0->rts_ds_mem_ctrl,
                                     RTS_DS_MEM_CTRL_STROBE_CMD_BEING_EXECUTED,
-                                    S2IO_BIT_RESET);
+                                    S2IO_BIT_RESET, true);
 }
 
 static const struct net_device_ops s2io_netdev_ops = {
        .ndo_get_stats          = s2io_get_stats,
        .ndo_start_xmit         = s2io_xmit,
        .ndo_validate_addr      = eth_validate_addr,
-       .ndo_set_rx_mode        = s2io_set_multicast,
+       .ndo_set_rx_mode        = s2io_ndo_set_multicast,
        .ndo_do_ioctl           = s2io_ioctl,
        .ndo_set_mac_address    = s2io_set_mac_addr,
        .ndo_change_mtu         = s2io_change_mtu,
        writeq(val64, &bar0->rmac_addr_cmd_mem);
        wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem,
                              RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING,
-                             S2IO_BIT_RESET);
+                             S2IO_BIT_RESET, true);
        tmp64 = readq(&bar0->rmac_addr_data0_mem);
        mac_down = (u32)tmp64;
        mac_up = (u32) (tmp64 >> 32);