int adapter_open(struct net_device *net) { struct net_adapter *adapter; int res = 0; adapter = netdev_priv(net); if (adapter == NULL || adapter->halted) { dump_debug("can't find adapter or halted"); return -ENODEV; } if (adapter->media_state) netif_wake_queue(net); else netif_stop_queue(net); if (netif_msg_ifup(adapter)) dump_debug("netif msg if up"); res = 0; dump_debug("adapter driver open success!!!!!!!"); return res; }
int hw_init(struct net_adapter *adapter) { /* set WIMAX_WAKEUP & WIMAX_IF_MODE0 */ adapter->pdata->set_mode(); /* initilize hardware info structure */ memset(&adapter->hw, 0x0, sizeof(struct hardware_info)); /* allocate sdio receive buffer once */ if (adapter->hw.receive_buffer == NULL) { dump_debug("Alloc ReceiveBuffer"); /* the extra 8 bytes space required to copy ethernet header */ adapter->hw.receive_buffer = kmalloc(SDIO_BUFFER_SIZE + 8, GFP_ATOMIC | GFP_DMA); if (adapter->hw.receive_buffer == NULL) { dump_debug("kmalloc fail!!"); return -ENOMEM; } } /* initialize sdio receive buffer */ memset(adapter->hw.receive_buffer, 0x0, SDIO_BUFFER_SIZE + 8); /* For sending data and control packets */ queue_init_list(adapter->hw.q_send.head); spin_lock_init(&adapter->hw.q_send.lock); init_waitqueue_head(&adapter->download_event); return STATUS_SUCCESS; }
void cmc7xx_sdio_reset(struct work_struct *work) { struct net_adapter *adapter = container_of(work, struct net_adapter, wimax_reset); u8 data[100]; sdio_claim_host(adapter->func); sdio_release_irq(adapter->func); sdio_release_host(adapter->func); if (wimax_cmc7xx_sdio_reset_comm(adapter->func->card)) dump_debug("%s: cmc7xx_sdio_reset_comm fail", __func__); sdio_claim_host(adapter->func); if (sdio_enable_func(adapter->func)) dump_debug("%s: sdio_enable_func fail", __func__); if (sdio_claim_irq(adapter->func, adapter_interrupt)) dump_debug("%s: sdio_claim_irq fail", __func__); if (sdio_set_block_size(adapter->func, 512)) dump_debug("%s: sdio_set_block_size fail", __func__); sdio_memcpy_toio(adapter->func, SDIO_TX_BANK_ADDR + 4, data, 32); sdio_release_host(adapter->func); }
static int cmc7xx_wimax_pm_callback(struct notifier_block *nfb, unsigned long action, void *ignored) { int ret = NOTIFY_DONE; struct wimax732_platform_data *pdata = container_of(nfb, struct wimax732_platform_data, pm_notifier); switch (action) { case PM_HIBERNATION_PREPARE: case PM_SUSPEND_PREPARE: pdata->g_cfg->wimax_suspend_prepare = true;; dump_debug("PM_SUSPEND_PREPARE: wimax"); ret = NOTIFY_OK; break; case PM_POST_HIBERNATION: case PM_POST_SUSPEND: pdata->g_cfg->wimax_suspend_prepare = false; dump_debug("PM_POST_SUSPEND: wimax"); ret = NOTIFY_OK; break; default: break; } return ret; }
int hw_device_wakeup(struct net_adapter *adapter) { int rc = 0; adapter->pdata->wakeup_assert(1); while (!adapter->pdata->is_modem_awake()) { if (rc == 0) dump_debug("hw_device_wakeup (CON0 status):" " waiting for modem awake"); rc++; if (rc > WAKEUP_MAX_TRY) { dump_debug("hw_device_wakeup (CON0 status):" " modem wake up time out!!"); break; } msleep(WAKEUP_TIMEOUT/2); adapter->pdata->wakeup_assert(0); msleep(WAKEUP_TIMEOUT/2); adapter->pdata->wakeup_assert(1); s3c_bat_use_wimax(1); } if (rc != 0) dump_debug("hw_device_wakeup (CON0 status): modem awake"); adapter->pdata->wakeup_assert(0); return 0; }
int uwbrdev_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long arg) { struct net_adapter *adapter; struct process_descriptor *process; int ret = 0; adapter = (struct net_adapter *)(file->private_data); if ((adapter == NULL) || adapter->halted) { dump_debug("can't find adapter or Device Removed"); return -ENODEV; } switch (cmd) { case CONTROL_IOCTL_WRITE_REQUEST: { struct eth_header *ctlhdr; memset(&g_tx_buffer, 0x0, sizeof(struct control_tx_buffer)); if ((char *)arg == NULL) { dump_debug("arg == NULL: return -EFAULT"); return -EFAULT; } g_tx_buffer.length = ((struct control_tx_buffer *)arg)->length; if (g_tx_buffer.length < WIMAX_MAX_TOTAL_SIZE) { if (copy_from_user(g_tx_buffer.data, (void *)(arg+sizeof(int)), g_tx_buffer.length)) return -EFAULT; } else return -EFBIG; spin_lock(&adapter->ctl.apps.lock); process = process_by_id(adapter, current->tgid); if (process == NULL) { dump_debug("process %d not found",\ current->tgid); ret = -EFAULT; spin_unlock(&adapter->ctl.apps.lock); break; } ctlhdr = (struct eth_header *)g_tx_buffer.data; process->type = ctlhdr->type; spin_unlock(&adapter->ctl.apps.lock); control_send(adapter, g_tx_buffer.data, g_tx_buffer.length); break; } default: dump_debug("uwbrdev_ioctl: " "unknown ioctl cmd: 0x%x", cmd); break; } /* switch (cmd) */ return ret; }
static int cmc732_setup_wake_irq(struct net_adapter *adapter) { int rc = -EIO; int irq; rc = gpio_request(WIMAX_INT, "gpio_wimax_int"); if (rc < 0) { dump_debug("%s: gpio %d request failed (%d)\n", __func__, WIMAX_INT, rc); return rc; } rc = gpio_direction_input(WIMAX_INT); if (rc < 0) { dump_debug("%s: failed to set gpio %d as input (%d)\n", __func__, WIMAX_INT, rc); goto err_gpio_direction_input; } irq = gpio_to_irq(WIMAX_INT); rc = request_irq(irq, wimax_hostwake_isr, IRQF_TRIGGER_FALLING, "wimax_int", adapter); if (rc < 0) { dump_debug("%s: request_irq(%d) failed for gpio %d (%d)\n", __func__, irq, WIMAX_INT, rc); goto err_request_irq; } rc = enable_irq_wake(irq); if (rc < 0) { dump_debug("%s: enable_irq_wake(%d) failed for gpio %d (%d)\n", __func__, irq, WIMAX_INT, rc); goto err_enable_irq_wake; } adapter->wake_irq = irq; tasklet_init(&adapter->hostwake_task, wimax_hostwake_task, (unsigned long)adapter); goto done; err_enable_irq_wake: free_irq(irq, adapter); err_request_irq: err_gpio_direction_input: gpio_free(WIMAX_INT); done: return rc; }
static int proc_write_sleepmode(struct file *foke, const char *buffer, unsigned long count, void *data) { if (buffer[0] == '0') { dump_debug("WiMAX Sleep Mode: VI"); g_pdata->g_cfg->sleep_mode = 0; } else if (buffer[0] == '1') { dump_debug("WiMAX Sleep Mode: IDLE"); g_pdata->g_cfg->sleep_mode = 1; } return count - 1; }
static int proc_write_dump(struct file *foke, const char *buffer, unsigned long count, void *data) { if (buffer[0] == '0') { dump_debug("Control Dump Disabled."); g_pdata->g_cfg->enable_dump_msg = 0; } else if (buffer[0] == '1') { dump_debug("Control Dump Enabled."); g_pdata->g_cfg->enable_dump_msg = 1; } return count - 1; }
int hw_start(struct net_adapter *adapter) { struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; if (load_wimax_image(g_cfg->wimax_mode)) return STATUS_UNSUCCESSFUL; adapter->download_complete = FALSE; if (adapter->downloading) { sdio_claim_host(adapter->func); send_cmd_packet(adapter, MSG_DRIVER_OK_REQ); sdio_release_host(adapter->func); switch (wait_event_interruptible_timeout (adapter->download_event, (adapter->download_complete == TRUE), msecs_to_jiffies(FWDOWNLOAD_TIMEOUT))) { case 0: /* timeout */ dump_debug("Error hw_start :" "F/W Download timeout failed"); adapter->halted = TRUE; return STATUS_UNSUCCESSFUL; case -ERESTARTSYS: /* Interrupted by signal */ dump_debug("Error hw_start : -ERESTARTSYS retry"); return STATUS_UNSUCCESSFUL; default: /* normal condition check */ if (adapter->removed == TRUE || adapter->halted == TRUE) { dump_debug("Error hw_start : " " F/W Download surprise removed"); return STATUS_UNSUCCESSFUL; } /*Setup hostwake interrupt*/ if (cmc732_setup_wake_irq(adapter) < 0) dump_debug("hw_start : " " Error setting up wimax_int"); break; } adapter->downloading = FALSE; } return STATUS_SUCCESS; }
int adapter_start_xmit(struct sk_buff *skb, struct net_device *net) { struct net_adapter *adapter = netdev_priv(net); int len; netif_stop_queue(net); if (!adapter->media_state || adapter->halted) { dump_debug("Driver already halted. Returning Failure..."); dev_kfree_skb(skb); adapter->netstats.tx_dropped++; net->trans_start = jiffies; adapter->XmitErr += 1; return 0; } len = ((skb->len) & 0x3f) ? skb->len : skb->len + 1; hw_send_data(adapter, skb->data, len, DATA_PACKET); dev_kfree_skb(skb); if (adapter->media_state) netif_wake_queue(adapter->net); return 0; }
u8 send_cmd_packet(struct net_adapter *adapter, u16 cmd_id) { struct hw_packet_header *pkt_hdr; struct wimax_msg_header *msg_hdr; u8 tx_buf[CMD_MSG_TOTAL_LENGTH]; int status = 0; u32 offset; u32 size; pkt_hdr = (struct hw_packet_header *)tx_buf; pkt_hdr->id0 = 'W'; pkt_hdr->id1 = 'C'; pkt_hdr->length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH); offset = sizeof(struct hw_packet_header); msg_hdr = (struct wimax_msg_header *)(tx_buf + offset); msg_hdr->type = be16_to_cpu(ETHERTYPE_DL); msg_hdr->id = be16_to_cpu(cmd_id); msg_hdr->length = be32_to_cpu(CMD_MSG_LENGTH); size = CMD_MSG_TOTAL_LENGTH; status = sd_send(adapter, tx_buf, size); if (status != STATUS_SUCCESS) { /* crc error or data error - set PCWRT '1' & send current type A packet again */ dump_debug("hwSdioWrite : crc or data error"); return status; } return status; }
void unload_wimax_image(void) { if (g_wimax_image.data != NULL) { dump_debug("Delete the Image Loaded"); vfree(g_wimax_image.data); g_wimax_image.data = NULL; } }
/* uwibro functions (send and receive control packet with WiMAX modem) */ int uwbrdev_open(struct inode *inode, struct file *file) { struct net_adapter *adapter; struct process_descriptor *process; if ((g_adapter == NULL) || g_adapter->halted) { dump_debug("can't find adapter or Device Removed"); return -ENODEV; } file->private_data = (void *)g_adapter; adapter = (struct net_adapter *)(file->private_data); dump_debug("open: tgid=%d", current->tgid); if (adapter->mac_ready != TRUE || adapter->halted) { dump_debug("Device not ready Retry.."); return -ENXIO; } process = process_by_id(adapter, current->tgid); if (process != NULL) { dump_debug("second open attemp from uid %d", current->tgid); return -EEXIST; } else { /* init new process descriptor */ process = (struct process_descriptor *) kmalloc(sizeof(struct process_descriptor), GFP_ATOMIC); if (process == NULL) { dump_debug("uwbrdev_open: kmalloc fail!!"); return -ENOMEM; } else { process->id = current->tgid; process->irp = FALSE; process->type = 0; init_waitqueue_head(&process->read_wait); spin_lock(&adapter->ctl.apps.lock); queue_put_tail(adapter->ctl.apps.process_list, process->node); spin_unlock(&adapter->ctl.apps.lock); } } return 0; }
void adapter_remove(struct sdio_func *func) { struct net_adapter *adapter = sdio_get_drvdata(func); dump_debug("%s", __func__); if (!adapter) { dump_debug("unregistering non-bound device?"); return; } adapter->ready = FALSE; adapter->pdata->g_cfg->card_removed = TRUE; if (adapter->media_state == MEDIA_CONNECTED) { netif_stop_queue(adapter->net); adapter->media_state = MEDIA_DISCONNECTED; } /* remove adapter from adapters array */ g_adapter = NULL; if (!adapter->removed) hw_stop(adapter); /* free hw in and out buffer */ if (adapter->downloading) { adapter->removed = TRUE; adapter->download_complete = TRUE; wake_up_interruptible(&adapter->download_event); } /* remove control process list */ control_remove(adapter); /*remove hardware interface */ hw_remove(adapter); misc_deregister(&uwibro_dev); if (adapter->net) unregister_netdev(adapter->net); cmc7xx_flush_skb(adapter); free_netdev(adapter->net); dump_debug("%s finished", __func__); return; }
static ssize_t dump_store(struct device *dev, struct device_attribute *attr, const char *buffer, size_t count) { struct wimax732_platform_data *pdata = dev_get_drvdata(dev); if (buffer[0] == '0') { dump_debug("Control Dump Disabled."); pdata->g_cfg->enable_dump_msg = 0; } else if (buffer[0] == '1') { dump_debug("Control Dump Enabled."); pdata->g_cfg->enable_dump_msg = 1; } return count - 1; }
/* swmxctl functions (power on/off and factory function test) */ int swmxdev_open(struct inode *inode, struct file *file) { struct wimax732_platform_data *pdata = container_of(file->private_data, struct wimax732_platform_data, swmxctl_dev); file->private_data = pdata; dump_debug("Device open by %d", current->tgid); return 0; }
u_int sd_send_data(struct net_adapter *adapter, struct buffer_descriptor *dsc) { int nRet = 0; int nWriteIdx; dsc->length += (dsc->length & 1) ? 1 : 0; #ifdef HARDWARE_USE_ALIGN_HEADER if (dsc->length > SDIO_MAX_BYTE_SIZE) dsc->length = (dsc->length + SDIO_MAX_BYTE_SIZE) & ~(SDIO_MAX_BYTE_SIZE); #endif if (adapter->halted) { dump_debug("Halted Already"); return STATUS_UNSUCCESSFUL; } hwSdioWriteBankIndex(adapter, &nWriteIdx, &nRet); if (nRet || (nWriteIdx < 0)) { dump_debug("sd_send_data : " " error fetch bank index!! nRet = %d", nRet); return STATUS_UNSUCCESSFUL; } sdio_writeb(adapter->func, (nWriteIdx + 1) % 15, SDIO_H2C_WP_REG, NULL); nRet = sdio_memcpy_toio(adapter->func, SDIO_TX_BANK_ADDR+(SDIO_BANK_SIZE * nWriteIdx)+4, dsc->buffer, dsc->length); if (nRet < 0) dump_debug("sd_send_data :" " error writing dsc packet!! nRet = %d", nRet); nRet = sdio_memcpy_toio(adapter->func, SDIO_TX_BANK_ADDR + (SDIO_BANK_SIZE * nWriteIdx), &(dsc->length), 4); if (nRet < 0) dump_debug("sd_send_data :" "error writing bank length info!! nRet = %d", nRet); return nRet; }
static int proc_read_eeprom(char *page, char **start, off_t off, int count, int *eof, void *data) { dump_debug("Write EEPROM!!"); eeprom_write_boot(); eeprom_write_rev(); return 0; }
static ssize_t eeprom_show(struct device *dev, struct device_attribute *attr, char *buf) { dump_debug("Write EEPROM!!"); eeprom_write_boot(); eeprom_write_rev(); return 0; }
int uwbrdev_release(struct inode *inode, struct file *file) { struct net_adapter *adapter; struct process_descriptor *process; int current_tgid = 0; dump_debug("release: tgid=%d, pid=%d", current->tgid, current->pid); adapter = (struct net_adapter *)(file->private_data); if (adapter == NULL) { dump_debug("can't find adapter"); return -ENODEV; } current_tgid = current->tgid; process = process_by_id(adapter, current_tgid); /* process is not exist. (open process != close process) */ if (process == NULL) { current_tgid = adapter->pdata->g_cfg->temp_tgid; dump_debug("release: pid changed: %d", current_tgid); process = process_by_id(adapter, current_tgid); } if (process != NULL) { /* RELEASE READ THREAD */ if (process->irp) { process->irp = FALSE; wake_up_interruptible(&process->read_wait); } spin_lock(&adapter->ctl.apps.lock); remove_process(adapter, current_tgid); spin_unlock(&adapter->ctl.apps.lock); } else { /*not found */ dump_debug("process %d not found", current_tgid); return -ESRCH; } return 0; }
void hw_remove(struct net_adapter *adapter) { struct buffer_descriptor *dsc; /* Free the pending data packets and control packets */ spin_lock(&adapter->hw.q_send.lock); while (!queue_empty(adapter->hw.q_send.head)) { dump_debug("Freeing q_send"); dsc = (struct buffer_descriptor *) queue_get_head(adapter->hw.q_send.head); if (!dsc) { dump_debug("Fail...node is null"); continue; } queue_remove_head(adapter->hw.q_send.head); kfree(dsc->buffer); kfree(dsc); } spin_unlock(&adapter->hw.q_send.lock); }
void s3c_bat_use_wimax(int onoff) { struct file *fp; fp = klib_fopen(WIMAX_BAT_SYSPATH, O_RDWR, 0); if (!fp) dump_debug("open fail"); if (onoff) klib_fwrite("1", 1, fp); else klib_fwrite("0", 1, fp); klib_fclose(fp); }
int load_wimax_image(int mode) { struct file *fp; int read_size = 0; if (mode == AUTH_MODE) /* download moed */ fp = klib_fopen(WIMAX_LOADER_PATH, O_RDONLY, 0); else fp = klib_fopen(WIMAX_IMAGE_PATH, O_RDONLY, 0); /* wimax mode */ if (fp) { if (g_wimax_image.data == NULL) {/* check already allocated */ g_wimax_image.data = (u8 *)vmalloc(MAX_WIMAXFW_SIZE); if (!g_wimax_image.data) { dump_debug("Error: Memory alloc failure"); klib_fclose(fp); return STATUS_UNSUCCESSFUL; } } memset(g_wimax_image.data, 0, MAX_WIMAXFW_SIZE); read_size = klib_flen_fcopy(g_wimax_image.data, MAX_WIMAXFW_SIZE, fp); g_wimax_image.size = read_size; g_wimax_image.address = CMC732_WIMAX_ADDRESS; g_wimax_image.offset = 0; klib_fclose(fp); } else { dump_debug("Error: WiMAX image file open failed"); return STATUS_UNSUCCESSFUL; } return STATUS_SUCCESS; }
/* get MAC address from device */ void hw_get_mac_address(void *data) { struct net_adapter *adapter = (struct net_adapter *)data; struct hw_private_packet req; int nResult = 0; int retry = 3; req.id0 = 'W'; req.id1 = 'P'; req.code = HwCodeMacRequest; req.value = 0; do { if (adapter == NULL) break; sdio_claim_host(adapter->func); nResult = sd_send(adapter, (u_char *)&req, sizeof(struct hw_private_packet)); sdio_release_host(adapter->func); if (nResult != STATUS_SUCCESS) dump_debug("hw_get_mac_address: sd_send fail!!"); msleep(300); retry--; /*in case we dont get MAC we need to release power lock and probe finsh */ if (!retry) { adapter->download_complete = TRUE; wake_up_interruptible(&adapter->download_event); msleep(100); } } while ((!adapter->mac_ready) && (!adapter->halted) && retry); adapter->pdata->g_cfg->powerup_done = true ; dump_debug("MAC thread exit"); return; }
static int wimax_remove(struct platform_device *pdev) { struct wimax732_platform_data *pdata = pdev->dev.platform_data; dump_debug("SDIO driver Uninstall"); /* destroy wake locks */ wake_lock_destroy(&pdata->g_cfg->wimax_wake_lock); wake_lock_destroy(&pdata->g_cfg->wimax_rxtx_lock); wake_lock_destroy(&pdata->g_cfg->wimax_tx_lock); class_destroy(pdata->wimax_class); cmc7xx_unregister_pm_notifier(pdata); sdio_unregister_driver(&adapter_driver); misc_deregister(&pdata->swmxctl_dev); mutex_destroy(&pdata->g_cfg->rx_lock); mutex_destroy(&pdata->g_cfg->power_mutex); return 0; }
static int gpio_wimax_power(int enable) { if (!enable) goto wimax_power_off; if (gpio_get_value(GPIO_WIMAX_EN)) { dump_debug("Already Wimax powered ON"); return WIMAX_ALREADY_POWER_ON; } while (!wimax_config.card_removed) msleep(100); dump_debug("Wimax power ON"); if (wimax_config.wimax_mode != SDIO_MODE) { switch_usb_wimax(); s3c_bat_use_wimax(1); } if (wimax_config.wimax_mode == WTM_MODE) { store_uart_path(); switch_uart_wimax(); } switch_eeprom_wimax(); wimax_on_pin_conf(1); gpio_set_value(GPIO_WIMAX_EN, GPIO_LEVEL_HIGH); wimax_init_gpios(); wimax_pmic_set_voltage(); dump_debug("RESET"); gpio_set_value(GPIO_WIMAX_RESET_N, GPIO_LEVEL_LOW); mdelay(3); gpio_set_value(GPIO_WIMAX_RESET_N, GPIO_LEVEL_HIGH); msleep(400); wimax_hsmmc_presence_check(); return WIMAX_POWER_SUCCESS; wimax_power_off: if (!gpio_get_value(GPIO_WIMAX_EN)) { dump_debug("Already Wimax powered OFF"); return WIMAX_ALREADY_POWER_OFF; /* already power off */ } while (!wimax_config.powerup_done) { msleep(500); dump_debug("Wimax waiting for power Off "); } msleep(500); wimax_deinit_gpios(); dump_debug("Wimax power OFF"); wimax_hsmmc_presence_check(); msleep(500); if (wimax_config.wimax_mode != SDIO_MODE) { s3c_bat_use_wimax(0); } wimax_on_pin_conf(0); return WIMAX_POWER_SUCCESS; }
int adapter_ioctl(struct net_device *net, struct ifreq *rq, int cmd) { struct net_adapter *adapter = netdev_priv(net); if (adapter->halted) { dump_debug("Driver already halted. Returning Failure..."); return STATUS_UNSUCCESSFUL; } switch (cmd) { case SIOCETHTOOL: return netdev_ethtool_ioctl(net, (void *)rq->ifr_data); default: return -EOPNOTSUPP; } return 0; }
u8 send_image_info_packet(struct net_adapter *adapter, u16 cmd_id) { struct hw_packet_header *pkt_hdr; struct wimax_msg_header *msg_hdr; u32 image_info[4]; u8 tx_buf[IMAGE_INFO_MSG_TOTAL_LENGTH]; int status; u32 offset; u32 size; pkt_hdr = (struct hw_packet_header *)tx_buf; pkt_hdr->id0 = 'W'; pkt_hdr->id1 = 'C'; pkt_hdr->length = be16_to_cpu(IMAGE_INFO_MSG_TOTAL_LENGTH); offset = sizeof(struct hw_packet_header); msg_hdr = (struct wimax_msg_header *)(tx_buf + offset); msg_hdr->type = be16_to_cpu(ETHERTYPE_DL); msg_hdr->id = be16_to_cpu(cmd_id); msg_hdr->length = be32_to_cpu(IMAGE_INFO_MSG_LENGTH); image_info[0] = 0; image_info[1] = be32_to_cpu(g_wimax_image.size); image_info[2] = be32_to_cpu(g_wimax_image.address); image_info[3] = 0; offset += sizeof(struct wimax_msg_header); memcpy(&(tx_buf[offset]), image_info, sizeof(image_info)); size = IMAGE_INFO_MSG_TOTAL_LENGTH; status = sd_send(adapter, tx_buf, size); if (status != STATUS_SUCCESS) { /* * crc error or data error - * set PCWRT '1' & send current type A packet again */ dump_debug("hwSdioWrite : crc error"); return status; } return status; }
int wimax_suspend(struct platform_device *pdev, pm_message_t state) { struct wimax732_platform_data *pdata; dump_debug("[wimax] %s", __func__); if (!g_adapter) return 0; pdata = pdev->dev.platform_data; /* AP active pin LOW */ pdata->signal_ap_active(0); /* display WiMAX uart msg during AP suspend */ if (pdata->g_cfg->enable_dump_msg == 1) { msleep(10); pdata->uart_wimax(); } return 0; }