/* Return packet for packet buffer freeing */ void hw_return_packet(struct net_adapter *adapter, u_short type) { struct buffer_descriptor *curElem; struct buffer_descriptor *prevElem = NULL; if (queue_empty(adapter->ctl.q_received.head)) return; /* first time get head needed to get the dsc nodes */ curElem = (struct buffer_descriptor *) queue_get_head(adapter->ctl.q_received.head); for ( ; curElem != NULL; prevElem = curElem, curElem = (struct buffer_descriptor *)curElem->node.next) { if (curElem->type == type) { /* process found*/ if (prevElem == NULL) { /* First node or only one node present to delete */ adapter->ctl.q_received.head.next = ((struct list_head *)curElem)->next; if (!((adapter->ctl.q_received.head).next)) { /* rechain list pointer to next link */ /* if the list pointer is null, null out the reverse link */ (adapter->ctl.q_received.head).prev = NULL; } } else if (((struct list_head *)curElem)->next == NULL) { /* last node */ ((struct list_head *)prevElem)->next = NULL; (adapter->ctl.q_received.head).prev = (struct list_head *)(&prevElem); } else { /* middle node */ ((struct list_head *)prevElem)->next = ((struct list_head *)curElem)->next; } kfree(curElem->buffer); kfree(curElem); break; } } }
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 hw_transmit_thread(struct work_struct *work) { struct buffer_descriptor *dsc; struct hw_private_packet hdr; struct net_adapter *adapter; int nRet = 0; adapter = container_of(work, struct net_adapter, transmit_work); struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; wake_lock_timeout(&g_cfg->wimax_rxtx_lock, 0.2 * HZ); mutex_lock(&adapter->rx_lock); if (!gpio_get_value(WIMAX_EN)) { dump_debug("WiMAX Power OFF!! (TX)"); adapter->halted = TRUE; return; } /* prevent WiMAX modem suspend during tx phase */ mutex_lock(&g_cfg->suspend_mutex); hw_device_wakeup(adapter); while (!queue_empty(adapter->hw.q_send.head)) { if (adapter->halted) { /* send stop message */ hdr.id0 = 'W'; hdr.id1 = 'P'; hdr.code = HwCodeHaltedIndication; hdr.value = 0; if (sd_send(adapter, (unsigned char *)&hdr, sizeof(struct hw_private_packet))) dump_debug("halted," " send HaltIndication to FW err"); break; } dsc = (struct buffer_descriptor *) queue_get_head(adapter->hw.q_send.head); if (!dsc->buffer) { dump_debug("dsc->buffer is NULL"); break; } if (!dsc) { dump_debug("Fail...node is null"); mutex_unlock(&g_cfg->suspend_mutex); break; } sdio_claim_host(adapter->func); nRet = sd_send_data(adapter, dsc); sdio_release_host(adapter->func); queue_remove_head(adapter->hw.q_send.head); kfree(dsc->buffer); kfree(dsc); if (nRet != STATUS_SUCCESS) { dump_debug("SendData Fail******"); ++adapter->XmitErr; if (nRet == -ENOMEDIUM || nRet == /*-ETIMEOUT*/-110) { adapter->halted = TRUE; break; } } } mutex_unlock(&g_cfg->suspend_mutex); mutex_unlock(&adapter->rx_lock); return ; }
bool queue_is_empty(Queue *queue){ return (0 == queue_get_size(queue)) && (queue_get_head(queue) == queue_get_tail(queue)); }
Item queue_back(Queue *queue){ return queue_get_head(queue)->next->item; }