+ clear_bit(0, &(nic->link_state));
+}
+
+static void s2io_card_down(nic_t * sp)
+{
+ int cnt = 0;
+ XENA_dev_config_t __iomem *bar0 = sp->bar0;
+ unsigned long flags;
+ register u64 val64 = 0;
+
+ /* If s2io_set_link task is executing, wait till it completes. */
+ while (test_and_set_bit(0, &(sp->link_state))) {
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ / 20);
+ }
+ atomic_set(&sp->card_state, CARD_DOWN);
+
+ /* disable Tx and Rx traffic on the NIC */
+ stop_nic(sp);
+
+ /* Kill tasklet. */
+ tasklet_kill(&sp->task);
+
+ /* Check if the device is Quiescent and then Reset the NIC */
+ do {
+ val64 = readq(&bar0->adapter_status);
+ if (verify_xena_quiescence(val64, sp->device_enabled_once)) {
+ break;
+ }
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ schedule_timeout(HZ / 20);
+ cnt++;
+ if (cnt == 10) {
+ DBG_PRINT(ERR_DBG,
+ "s2io_close:Device not Quiescent ");
+ DBG_PRINT(ERR_DBG, "adaper status reads 0x%llx\n",
+ (unsigned long long) val64);
+ break;
+ }
+ } while (1);
+ spin_lock_irqsave(&sp->tx_lock, flags);
+ s2io_reset(sp);
+
+ /* Free all unused Tx and Rx buffers */
+ free_tx_buffers(sp);
+ free_rx_buffers(sp);
+
+ spin_unlock_irqrestore(&sp->tx_lock, flags);
+ clear_bit(0, &(sp->link_state));
+}
+
+static int s2io_card_up(nic_t * sp)
+{
+ int i, ret;
+ mac_info_t *mac_control;
+ struct config_param *config;
+ struct net_device *dev = (struct net_device *) sp->dev;
+
+ /* Initialize the H/W I/O registers */
+ if (init_nic(sp) != 0) {
+ DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n",
+ dev->name);
+ return -ENODEV;
+ }
+
+ /*
+ * Initializing the Rx buffers. For now we are considering only 1
+ * Rx ring and initializing buffers into 30 Rx blocks
+ */
+ mac_control = &sp->mac_control;
+ config = &sp->config;
+
+ for (i = 0; i < config->rx_ring_num; i++) {
+ if ((ret = fill_rx_buffers(sp, i))) {
+ DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n",
+ dev->name);
+ s2io_reset(sp);
+ free_rx_buffers(sp);
+ return -ENOMEM;
+ }
+ DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
+ atomic_read(&sp->rx_bufs_left[i]));
+ }
+
+ /* Setting its receive mode */
+ s2io_set_multicast(dev);
+
+ /* Enable tasklet for the device */
+ tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev);
+
+ /* Enable Rx Traffic and interrupts on the NIC */
+ if (start_nic(sp)) {
+ DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name);
+ tasklet_kill(&sp->task);
+ s2io_reset(sp);
+ free_irq(dev->irq, dev);
+ free_rx_buffers(sp);
+ return -ENODEV;
+ }
+
+ atomic_set(&sp->card_state, CARD_UP);
+ return 0;