本文整理汇总了C++中skb_queue_tail函数的典型用法代码示例。如果您正苦于以下问题:C++ skb_queue_tail函数的具体用法?C++ skb_queue_tail怎么用?C++ skb_queue_tail使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了skb_queue_tail函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: handle_recv_skb
static int handle_recv_skb(struct capiminor *mp, struct sk_buff *skb)
{
struct sk_buff *nskb;
unsigned int datalen;
u16 errcode, datahandle;
datalen = skb->len - CAPIMSG_LEN(skb->data);
if (mp->tty) {
if (mp->tty->ldisc.receive_buf == 0) {
printk(KERN_ERR "capi: ldisc has no receive_buf function\n");
return -1;
}
if (mp->ttyinstop) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: recv tty throttled\n");
#endif
return -1;
}
if (mp->tty->ldisc.receive_room &&
mp->tty->ldisc.receive_room(mp->tty) < datalen) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: no room in tty\n");
#endif
return -1;
}
if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
return -1;
}
datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
errcode = (*capifuncs->capi_put_message)(mp->applid, nskb);
if (errcode != CAPI_NOERROR) {
printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
errcode);
kfree_skb(nskb);
return -1;
}
(void)skb_pull(skb, CAPIMSG_LEN(skb->data));
#ifdef _DEBUG_DATAFLOW
printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => ldisc\n",
datahandle, skb->len);
#endif
mp->tty->ldisc.receive_buf(mp->tty, skb->data, 0, skb->len);
kfree_skb(skb);
return 0;
} else if (mp->file) {
if (skb_queue_len(&mp->recvqueue) > CAPINC_MAX_RECVQUEUE) {
#if defined(_DEBUG_DATAFLOW) || defined(_DEBUG_TTYFUNCS)
printk(KERN_DEBUG "capi: no room in raw queue\n");
#endif
return -1;
}
if ((nskb = gen_data_b3_resp_for(mp, skb)) == 0) {
printk(KERN_ERR "capi: gen_data_b3_resp failed\n");
return -1;
}
datahandle = CAPIMSG_U16(skb->data,CAPIMSG_BASELEN+4);
errcode = (*capifuncs->capi_put_message)(mp->applid, nskb);
if (errcode != CAPI_NOERROR) {
printk(KERN_ERR "capi: send DATA_B3_RESP failed=%x\n",
errcode);
kfree_skb(nskb);
return -1;
}
(void)skb_pull(skb, CAPIMSG_LEN(skb->data));
#ifdef _DEBUG_DATAFLOW
printk(KERN_DEBUG "capi: DATA_B3_RESP %u len=%d => raw\n",
datahandle, skb->len);
#endif
skb_queue_tail(&mp->recvqueue, skb);
wake_up_interruptible(&mp->recvwait);
return 0;
}
#ifdef _DEBUG_DATAFLOW
printk(KERN_DEBUG "capi: currently no receiver\n");
#endif
return -1;
}
开发者ID:romanalexander,项目名称:Trickles,代码行数:79,代码来源:capi.c
示例2: hscx_interrupt
static void
hscx_interrupt(struct IsdnCardState *cs, u_char val, u_char hscx)
{
u_char r;
struct BCState *bcs = cs->bcs + hscx;
struct sk_buff *skb;
int fifo_size = test_bit(HW_IPAC, &cs->HW_Flags)? 64: 32;
int count;
if (!test_bit(BC_FLG_INIT, &bcs->Flag))
return;
if (val & 0x80) { /* RME */
r = READHSCX(cs, hscx, HSCX_RSTA);
if ((r & 0xf0) != 0xa0) {
if (!(r & 0x80)) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX invalid frame");
#ifdef ERROR_STATISTIC
bcs->err_inv++;
#endif
}
if ((r & 0x40) && bcs->mode) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX RDO mode=%d",
bcs->mode);
#ifdef ERROR_STATISTIC
bcs->err_rdo++;
#endif
}
if (!(r & 0x20)) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "HSCX CRC error");
#ifdef ERROR_STATISTIC
bcs->err_crc++;
#endif
}
WriteHSCXCMDR(cs, hscx, 0x80);
} else {
count = READHSCX(cs, hscx, HSCX_RBCL) & (
test_bit(HW_IPAC, &cs->HW_Flags)? 0x3f: 0x1f);
if (count == 0)
count = fifo_size;
hscx_empty_fifo(bcs, count);
if ((count = bcs->hw.hscx.rcvidx - 1) > 0) {
if (cs->debug & L1_DEB_HSCX_FIFO)
debugl1(cs, "HX Frame %d", count);
if (!(skb = dev_alloc_skb(count)))
printk(KERN_WARNING "HSCX: receive out of memory\n");
else {
memcpy(skb_put(skb, count), bcs->hw.hscx.rcvbuf, count);
skb_queue_tail(&bcs->rqueue, skb);
}
}
}
bcs->hw.hscx.rcvidx = 0;
schedule_event(bcs, B_RCVBUFREADY);
}
if (val & 0x40) { /* RPF */
hscx_empty_fifo(bcs, fifo_size);
if (bcs->mode == L1_MODE_TRANS) {
/* receive audio data */
if (!(skb = dev_alloc_skb(fifo_size)))
printk(KERN_WARNING "HiSax: receive out of memory\n");
else {
memcpy(skb_put(skb, fifo_size), bcs->hw.hscx.rcvbuf, fifo_size);
skb_queue_tail(&bcs->rqueue, skb);
}
bcs->hw.hscx.rcvidx = 0;
schedule_event(bcs, B_RCVBUFREADY);
}
}
if (val & 0x10) { /* XPR */
if (bcs->tx_skb) {
if (bcs->tx_skb->len) {
hscx_fill_fifo(bcs);
return;
} else {
if (test_bit(FLG_LLI_L1WAKEUP,&bcs->st->lli.flag) &&
(PACKET_NOACK != bcs->tx_skb->pkt_type)) {
u_long flags;
spin_lock_irqsave(&bcs->aclock, flags);
bcs->ackcnt += bcs->hw.hscx.count;
spin_unlock_irqrestore(&bcs->aclock, flags);
schedule_event(bcs, B_ACKPENDING);
}
dev_kfree_skb_irq(bcs->tx_skb);
bcs->hw.hscx.count = 0;
bcs->tx_skb = NULL;
}
}
if ((bcs->tx_skb = skb_dequeue(&bcs->squeue))) {
bcs->hw.hscx.count = 0;
test_and_set_bit(BC_FLG_BUSY, &bcs->Flag);
hscx_fill_fifo(bcs);
} else {
test_and_clear_bit(BC_FLG_BUSY, &bcs->Flag);
schedule_event(bcs, B_XMTBUFREADY);
}
}
//.........这里部分代码省略.........
开发者ID:tch-opensrc,项目名称:TC72XX_LxG1.0.10mp5_OpenSrc,代码行数:101,代码来源:hscx_irq.c
示例3: btusb_probe
//.........这里部分代码省略.........
INIT_WORK(&data->waker, btusb_waker);
spin_lock_init(&data->txlock);
init_usb_anchor(&data->tx_anchor);
init_usb_anchor(&data->intr_anchor);
init_usb_anchor(&data->bulk_anchor);
init_usb_anchor(&data->isoc_anchor);
init_usb_anchor(&data->deferred);
hdev = hci_alloc_dev();
if (!hdev) {
kfree(data);
return -ENOMEM;
}
hdev->bus = HCI_USB;
hdev->driver_data = data;
data->hdev = hdev;
SET_HCIDEV_DEV(hdev, &intf->dev);
hdev->open = btusb_open;
hdev->close = btusb_close;
hdev->flush = btusb_flush;
hdev->send = btusb_send_frame;
hdev->destruct = btusb_destruct;
hdev->notify = btusb_notify;
hdev->owner = THIS_MODULE;
/* Interface numbers are hardcoded in the specification */
data->isoc = usb_ifnum_to_if(data->udev, 1);
if (!reset)
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
if (force_scofix || id->driver_info & BTUSB_WRONG_SCO_MTU) {
if (!disable_scofix)
set_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks);
}
if (id->driver_info & BTUSB_BROKEN_ISOC)
data->isoc = NULL;
if (id->driver_info & BTUSB_DIGIANSWER) {
data->cmdreq_type = USB_TYPE_VENDOR;
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
}
if (id->driver_info & BTUSB_CSR) {
struct usb_device *udev = data->udev;
/* Old firmware would otherwise execute USB reset */
if (le16_to_cpu(udev->descriptor.bcdDevice) < 0x117)
set_bit(HCI_QUIRK_NO_RESET, &hdev->quirks);
}
if (id->driver_info & BTUSB_SNIFFER) {
struct usb_device *udev = data->udev;
/* New sniffer firmware has crippled HCI interface */
if (le16_to_cpu(udev->descriptor.bcdDevice) > 0x997)
set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks);
data->isoc = NULL;
}
if (id->driver_info & BTUSB_BCM92035) {
unsigned char cmd[] = { 0x3b, 0xfc, 0x01, 0x00 };
struct sk_buff *skb;
skb = bt_skb_alloc(sizeof(cmd), GFP_KERNEL);
if (skb) {
memcpy(skb_put(skb, sizeof(cmd)), cmd, sizeof(cmd));
skb_queue_tail(&hdev->driver_init, skb);
}
}
if (data->isoc) {
err = usb_driver_claim_interface(&btusb_driver,
data->isoc, data);
if (err < 0) {
hci_free_dev(hdev);
kfree(data);
return err;
}
}
err = hci_register_dev(hdev);
if (err < 0) {
hci_free_dev(hdev);
kfree(data);
return err;
}
usb_set_intfdata(intf, data);
return 0;
}
开发者ID:zuiqingfeng,项目名称:ZuiQingFeng_HTC_DHD_3.0_Kernel,代码行数:101,代码来源:btusb.c
示例4: clip_start_xmit
static int clip_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct clip_priv *clip_priv = PRIV(dev);
struct atmarp_entry *entry;
struct atm_vcc *vcc;
int old;
unsigned long flags;
pr_debug("clip_start_xmit (skb %p)\n", skb);
if (!skb->dst) {
printk(KERN_ERR "clip_start_xmit: skb->dst == NULL\n");
dev_kfree_skb(skb);
clip_priv->stats.tx_dropped++;
return 0;
}
if (!skb->dst->neighbour) {
#if 0
skb->dst->neighbour = clip_find_neighbour(skb->dst, 1);
if (!skb->dst->neighbour) {
dev_kfree_skb(skb); /* lost that one */
clip_priv->stats.tx_dropped++;
return 0;
}
#endif
printk(KERN_ERR "clip_start_xmit: NO NEIGHBOUR !\n");
dev_kfree_skb(skb);
clip_priv->stats.tx_dropped++;
return 0;
}
entry = NEIGH2ENTRY(skb->dst->neighbour);
if (!entry->vccs) {
if (time_after(jiffies, entry->expires)) {
/* should be resolved */
entry->expires = jiffies + ATMARP_RETRY_DELAY * HZ;
to_atmarpd(act_need, PRIV(dev)->number, entry->ip);
}
if (entry->neigh->arp_queue.qlen < ATMARP_MAX_UNRES_PACKETS)
skb_queue_tail(&entry->neigh->arp_queue, skb);
else {
dev_kfree_skb(skb);
clip_priv->stats.tx_dropped++;
}
return 0;
}
pr_debug("neigh %p, vccs %p\n", entry, entry->vccs);
ATM_SKB(skb)->vcc = vcc = entry->vccs->vcc;
pr_debug("using neighbour %p, vcc %p\n", skb->dst->neighbour, vcc);
if (entry->vccs->encap) {
void *here;
here = skb_push(skb, RFC1483LLC_LEN);
memcpy(here, llc_oui, sizeof(llc_oui));
((__be16 *) here)[3] = skb->protocol;
}
atomic_add(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
ATM_SKB(skb)->atm_options = vcc->atm_options;
entry->vccs->last_use = jiffies;
pr_debug("atm_skb(%p)->vcc(%p)->dev(%p)\n", skb, vcc, vcc->dev);
old = xchg(&entry->vccs->xoff, 1); /* assume XOFF ... */
if (old) {
printk(KERN_WARNING "clip_start_xmit: XOFF->XOFF transition\n");
return 0;
}
clip_priv->stats.tx_packets++;
clip_priv->stats.tx_bytes += skb->len;
vcc->send(vcc, skb);
if (atm_may_send(vcc, 0)) {
entry->vccs->xoff = 0;
return 0;
}
spin_lock_irqsave(&clip_priv->xoff_lock, flags);
netif_stop_queue(dev); /* XOFF -> throttle immediately */
barrier();
if (!entry->vccs->xoff)
netif_start_queue(dev);
/* Oh, we just raced with clip_pop. netif_start_queue should be
good enough, because nothing should really be asleep because
of the brief netif_stop_queue. If this isn't true or if it
changes, use netif_wake_queue instead. */
spin_unlock_irqrestore(&clip_priv->xoff_lock, flags);
return 0;
}
开发者ID:458941968,项目名称:mini2440-kernel-2.6.29,代码行数:82,代码来源:clip.c
示例5: mwifiex_usb_recv
/* This function handles received packet. Necessary action is taken based on
* cmd/event/data.
*/
static int mwifiex_usb_recv(struct mwifiex_adapter *adapter,
struct sk_buff *skb, u8 ep)
{
u32 recv_type;
__le32 tmp;
int ret;
if (adapter->hs_activated)
mwifiex_process_hs_config(adapter);
if (skb->len < INTF_HEADER_LEN) {
mwifiex_dbg(adapter, ERROR,
"%s: invalid skb->len\n", __func__);
return -1;
}
switch (ep) {
case MWIFIEX_USB_EP_CMD_EVENT:
mwifiex_dbg(adapter, EVENT,
"%s: EP_CMD_EVENT\n", __func__);
skb_copy_from_linear_data(skb, &tmp, INTF_HEADER_LEN);
recv_type = le32_to_cpu(tmp);
skb_pull(skb, INTF_HEADER_LEN);
switch (recv_type) {
case MWIFIEX_USB_TYPE_CMD:
if (skb->len > MWIFIEX_SIZE_OF_CMD_BUFFER) {
mwifiex_dbg(adapter, ERROR,
"CMD: skb->len too large\n");
ret = -1;
goto exit_restore_skb;
} else if (!adapter->curr_cmd) {
mwifiex_dbg(adapter, WARN, "CMD: no curr_cmd\n");
if (adapter->ps_state == PS_STATE_SLEEP_CFM) {
mwifiex_process_sleep_confirm_resp(
adapter, skb->data,
skb->len);
ret = 0;
goto exit_restore_skb;
}
ret = -1;
goto exit_restore_skb;
}
adapter->curr_cmd->resp_skb = skb;
adapter->cmd_resp_received = true;
break;
case MWIFIEX_USB_TYPE_EVENT:
if (skb->len < sizeof(u32)) {
mwifiex_dbg(adapter, ERROR,
"EVENT: skb->len too small\n");
ret = -1;
goto exit_restore_skb;
}
skb_copy_from_linear_data(skb, &tmp, sizeof(u32));
adapter->event_cause = le32_to_cpu(tmp);
mwifiex_dbg(adapter, EVENT,
"event_cause %#x\n", adapter->event_cause);
if (skb->len > MAX_EVENT_SIZE) {
mwifiex_dbg(adapter, ERROR,
"EVENT: event body too large\n");
ret = -1;
goto exit_restore_skb;
}
memcpy(adapter->event_body, skb->data +
MWIFIEX_EVENT_HEADER_LEN, skb->len);
adapter->event_received = true;
adapter->event_skb = skb;
break;
default:
mwifiex_dbg(adapter, ERROR,
"unknown recv_type %#x\n", recv_type);
return -1;
}
break;
case MWIFIEX_USB_EP_DATA:
mwifiex_dbg(adapter, DATA, "%s: EP_DATA\n", __func__);
if (skb->len > MWIFIEX_RX_DATA_BUF_SIZE) {
mwifiex_dbg(adapter, ERROR,
"DATA: skb->len too large\n");
return -1;
}
skb_queue_tail(&adapter->rx_data_q, skb);
adapter->data_received = true;
atomic_inc(&adapter->rx_pending);
break;
default:
mwifiex_dbg(adapter, ERROR,
"%s: unknown endport %#x\n", __func__, ep);
return -1;
}
return -EINPROGRESS;
//.........这里部分代码省略.........
开发者ID:Lyude,项目名称:linux,代码行数:101,代码来源:usb.c
示例6: kmalloc
static struct sk_buff_head *msm_ipc_router_build_msg(unsigned int num_sect,
struct iovec const *msg_sect,
size_t total_len)
{
struct sk_buff_head *msg_head;
struct sk_buff *msg;
int i, copied, first = 1;
int data_size = 0, request_size, offset;
void *data;
for (i = 0; i < num_sect; i++)
data_size += msg_sect[i].iov_len;
if (!data_size)
return NULL;
msg_head = kmalloc(sizeof(struct sk_buff_head), GFP_KERNEL);
if (!msg_head) {
pr_err("%s: cannot allocate skb_head\n", __func__);
return NULL;
}
skb_queue_head_init(msg_head);
for (copied = 1, i = 0; copied && (i < num_sect); i++) {
data_size = msg_sect[i].iov_len;
offset = 0;
while (offset != msg_sect[i].iov_len) {
request_size = data_size;
if (first)
request_size += IPC_ROUTER_HDR_SIZE;
msg = alloc_skb(request_size, GFP_KERNEL);
if (!msg) {
if (request_size <= (PAGE_SIZE/2)) {
pr_err("%s: cannot allocated skb\n",
__func__);
goto msg_build_failure;
}
data_size = data_size / 2;
continue;
}
if (first) {
skb_reserve(msg, IPC_ROUTER_HDR_SIZE);
first = 0;
}
data = skb_put(msg, data_size);
copied = !copy_from_user(msg->data,
msg_sect[i].iov_base + offset,
data_size);
if (!copied) {
pr_err("%s: copy_from_user failed\n",
__func__);
kfree_skb(msg);
goto msg_build_failure;
}
skb_queue_tail(msg_head, msg);
offset += data_size;
data_size = msg_sect[i].iov_len - offset;
}
}
return msg_head;
msg_build_failure:
while (!skb_queue_empty(msg_head)) {
msg = skb_dequeue(msg_head);
kfree_skb(msg);
}
kfree(msg_head);
return NULL;
}
开发者ID:CL0SeY,项目名称:i957kernel,代码行数:72,代码来源:ipc_socket.c
示例7: isac_interrupt
void
isac_interrupt(struct IsdnCardState *cs, u_char val)
{
u_char exval, v1;
struct sk_buff *skb;
unsigned int count;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC interrupt %x", val);
if (val & 0x80) { /* RME */
exval = cs->readisac(cs, ISAC_RSTA);
if ((exval & 0x70) != 0x20) {
if (exval & 0x40) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "ISAC RDO");
#ifdef ERROR_STATISTIC
cs->err_rx++;
#endif
}
if (!(exval & 0x20)) {
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "ISAC CRC error");
#ifdef ERROR_STATISTIC
cs->err_crc++;
#endif
}
cs->writeisac(cs, ISAC_CMDR, 0x80);
} else {
count = cs->readisac(cs, ISAC_RBCL) & 0x1f;
if (count == 0)
count = 32;
isac_empty_fifo(cs, count);
if ((count = cs->rcvidx) > 0) {
cs->rcvidx = 0;
if (!(skb = alloc_skb(count, GFP_ATOMIC)))
printk(KERN_WARNING "HiSax: D receive out of memory\n");
else {
memcpy(skb_put(skb, count), cs->rcvbuf, count);
skb_queue_tail(&cs->rq, skb);
}
}
}
cs->rcvidx = 0;
schedule_event(cs, D_RCVBUFREADY);
}
if (val & 0x40) { /* RPF */
isac_empty_fifo(cs, 32);
}
if (val & 0x20) { /* RSC */
/* never */
if (cs->debug & L1_DEB_WARN)
debugl1(cs, "ISAC RSC interrupt");
}
if (val & 0x10) { /* XPR */
if (test_and_clear_bit(FLG_DBUSY_TIMER, &cs->HW_Flags))
del_timer(&cs->dbusytimer);
if (test_and_clear_bit(FLG_L1_DBUSY, &cs->HW_Flags))
schedule_event(cs, D_CLEARBUSY);
if (cs->tx_skb) {
if (cs->tx_skb->len) {
isac_fill_fifo(cs);
goto afterXPR;
} else {
dev_kfree_skb_irq(cs->tx_skb);
cs->tx_cnt = 0;
cs->tx_skb = NULL;
}
}
if ((cs->tx_skb = skb_dequeue(&cs->sq))) {
cs->tx_cnt = 0;
isac_fill_fifo(cs);
} else
schedule_event(cs, D_XMTBUFREADY);
}
afterXPR:
if (val & 0x04) { /* CISQ */
exval = cs->readisac(cs, ISAC_CIR0);
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ISAC CIR0 %02X", exval );
if (exval & 2) {
cs->dc.isac.ph_state = (exval >> 2) & 0xf;
if (cs->debug & L1_DEB_ISAC)
debugl1(cs, "ph_state change %x", cs->dc.isac.ph_state);
schedule_event(cs, D_L1STATECHANGE);
}
开发者ID:nighthawk149,项目名称:fvs318g-cfw,代码行数:85,代码来源:isac.c
示例8: mpc_push
static void mpc_push(struct atm_vcc *vcc, struct sk_buff *skb)
{
struct net_device *dev = (struct net_device *)vcc->proto_data;
struct sk_buff *new_skb;
eg_cache_entry *eg;
struct mpoa_client *mpc;
uint32_t tag;
char *tmp;
ddprintk("mpoa: (%s) mpc_push:\n", dev->name);
if (skb == NULL) {
dprintk("mpoa: (%s) mpc_push: null skb, closing VCC\n", dev->name);
mpc_vcc_close(vcc, dev);
return;
}
skb->dev = dev;
if (memcmp(skb->data, &llc_snap_mpoa_ctrl, sizeof(struct llc_snap_hdr)) == 0) {
dprintk("mpoa: (%s) mpc_push: control packet arrived\n", dev->name);
skb_queue_tail(&vcc->sk->receive_queue, skb); /* Pass control packets to daemon */
wake_up(&vcc->sleep);
return;
}
/* data coming over the shortcut */
atm_return(vcc, skb->truesize);
mpc = find_mpc_by_lec(dev);
if (mpc == NULL) {
printk("mpoa: (%s) mpc_push: unknown MPC\n", dev->name);
return;
}
if (memcmp(skb->data, &llc_snap_mpoa_data_tagged, sizeof(struct llc_snap_hdr)) == 0) { /* MPOA tagged data */
ddprintk("mpoa: (%s) mpc_push: tagged data packet arrived\n", dev->name);
} else if (memcmp(skb->data, &llc_snap_mpoa_data, sizeof(struct llc_snap_hdr)) == 0) { /* MPOA data */
printk("mpoa: (%s) mpc_push: non-tagged data packet arrived\n", dev->name);
printk(" mpc_push: non-tagged data unsupported, purging\n");
dev_kfree_skb_any(skb);
return;
} else {
printk("mpoa: (%s) mpc_push: garbage arrived, purging\n", dev->name);
dev_kfree_skb_any(skb);
return;
}
tmp = skb->data + sizeof(struct llc_snap_hdr);
tag = *(uint32_t *)tmp;
eg = mpc->eg_ops->get_by_tag(tag, mpc);
if (eg == NULL) {
printk("mpoa: (%s) mpc_push: Didn't find egress cache entry, tag = %u\n",
dev->name,tag);
purge_egress_shortcut(vcc, NULL);
dev_kfree_skb_any(skb);
return;
}
/*
* See if ingress MPC is using shortcut we opened as a return channel.
* This means we have a bi-directional vcc opened by us.
*/
if (eg->shortcut == NULL) {
eg->shortcut = vcc;
printk("mpoa: (%s) mpc_push: egress SVC in use\n", dev->name);
}
skb_pull(skb, sizeof(struct llc_snap_hdr) + sizeof(tag)); /* get rid of LLC/SNAP header */
new_skb = skb_realloc_headroom(skb, eg->ctrl_info.DH_length); /* LLC/SNAP is shorter than MAC header :( */
dev_kfree_skb_any(skb);
if (new_skb == NULL){
mpc->eg_ops->put(eg);
return;
}
skb_push(new_skb, eg->ctrl_info.DH_length); /* add MAC header */
memcpy(new_skb->data, eg->ctrl_info.DLL_header, eg->ctrl_info.DH_length);
new_skb->protocol = eth_type_trans(new_skb, dev);
new_skb->nh.raw = new_skb->data;
eg->latest_ip_addr = new_skb->nh.iph->saddr;
eg->packets_rcvd++;
mpc->eg_ops->put(eg);
memset(ATM_SKB(new_skb), 0, sizeof(struct atm_skb_data));
netif_rx(new_skb);
return;
}
开发者ID:JBTech,项目名称:ralink_rt5350,代码行数:89,代码来源:mpc.c
示例9: fnic_rq_cmpl_frame_recv
//.........这里部分代码省略.........
u16 exchange_id, tmpl;
u8 sof = 0;
u8 eof = 0;
u32 fcp_bytes_written = 0;
unsigned long flags;
pci_unmap_single(fnic->pdev, buf->dma_addr, buf->len,
PCI_DMA_FROMDEVICE);
skb = buf->os_buf;
buf->os_buf = NULL;
cq_desc_dec(cq_desc, &type, &color, &q_number, &completed_index);
if (type == CQ_DESC_TYPE_RQ_FCP) {
cq_fcp_rq_desc_dec((struct cq_fcp_rq_desc *)cq_desc,
&type, &color, &q_number, &completed_index,
&eop, &sop, &fcoe_fc_crc_ok, &exchange_id,
&tmpl, &fcp_bytes_written, &sof, &eof,
&ingress_port, &packet_error,
&fcoe_enc_error, &fcs_ok, &vlan_stripped,
&vlan);
eth_hdrs_stripped = 1;
} else if (type == CQ_DESC_TYPE_RQ_ENET) {
cq_enet_rq_desc_dec((struct cq_enet_rq_desc *)cq_desc,
&type, &color, &q_number, &completed_index,
&ingress_port, &fcoe, &eop, &sop,
&rss_type, &csum_not_calc, &rss_hash,
&bytes_written, &packet_error,
&vlan_stripped, &vlan, &checksum,
&fcoe_sof, &fcoe_fc_crc_ok,
&fcoe_enc_error, &fcoe_eof,
&tcp_udp_csum_ok, &udp, &tcp,
&ipv4_csum_ok, &ipv6, &ipv4,
&ipv4_fragment, &fcs_ok);
eth_hdrs_stripped = 0;
} else {
/* wrong CQ type*/
shost_printk(KERN_ERR, fnic->lport->host,
"fnic rq_cmpl wrong cq type x%x\n", type);
goto drop;
}
if (!fcs_ok || packet_error || !fcoe_fc_crc_ok || fcoe_enc_error) {
FNIC_FCS_DBG(KERN_DEBUG, fnic->lport->host,
"fnic rq_cmpl fcoe x%x fcsok x%x"
" pkterr x%x fcoe_fc_crc_ok x%x, fcoe_enc_err"
" x%x\n",
fcoe, fcs_ok, packet_error,
fcoe_fc_crc_ok, fcoe_enc_error);
goto drop;
}
if (eth_hdrs_stripped)
fnic_import_rq_fc_frame(skb, fcp_bytes_written, sof, eof);
else if (fnic_import_rq_eth_pkt(skb, bytes_written))
goto drop;
fp = (struct fc_frame *)skb;
/*
* If frame is an ELS response that matches the cached FLOGI OX_ID,
* and is accept, issue flogi_reg_request copy wq request to firmware
* to register the S_ID and determine whether FC_OUI mode or GW mode.
*/
if (is_matching_flogi_resp_frame(fnic, fp)) {
if (!eth_hdrs_stripped) {
if (fc_frame_payload_op(fp) == ELS_LS_ACC) {
fnic_handle_flogi_resp(fnic, fp);
return;
}
/*
* Recd. Flogi reject. No point registering
* with fw, but forward to libFC
*/
goto forward;
}
goto drop;
}
if (!eth_hdrs_stripped)
goto drop;
forward:
spin_lock_irqsave(&fnic->fnic_lock, flags);
if (fnic->stop_rx_link_events) {
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
goto drop;
}
/* Use fr_flags to indicate whether succ. flogi resp or not */
fr_flags(fp) = 0;
fr_dev(fp) = fnic->lport;
spin_unlock_irqrestore(&fnic->fnic_lock, flags);
skb_queue_tail(&fnic->frame_queue, skb);
queue_work(fnic_event_queue, &fnic->frame_work);
return;
drop:
dev_kfree_skb_irq(skb);
}
开发者ID:AppEngine,项目名称:linux-2.6,代码行数:101,代码来源:fnic_fcs.c
示例10: usb_read_port_complete
void usb_read_port_complete(struct urb *purb, struct pt_regs *regs)
{
struct recv_buf *precvbuf = (struct recv_buf *)purb->context;
_adapter *padapter =(_adapter *)precvbuf->adapter;
struct recv_priv *precvpriv = &padapter->recvpriv;
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete!!!\n"));
ATOMIC_DEC(&(precvpriv->rx_pending_cnt));
if(RTW_CANNOT_RX(padapter))
{
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped(%d) OR bSurpriseRemoved(%d)\n", padapter->bDriverStopped, padapter->bSurpriseRemoved));
DBG_8192C("%s() RX Warning! bDriverStopped(%d) OR bSurpriseRemoved(%d) \n",
__FUNCTION__,padapter->bDriverStopped, padapter->bSurpriseRemoved);
goto exit;
}
if(purb->status==0)//SUCCESS
{
if ((purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE))
{
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete: (purb->actual_length > MAX_RECVBUF_SZ) || (purb->actual_length < RXDESC_SIZE)\n"));
rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
DBG_8192C("%s()-%d: RX Warning!\n", __FUNCTION__, __LINE__);
}
else
{
rtw_reset_continual_io_error(adapter_to_dvobj(padapter));
precvbuf->transfer_len = purb->actual_length;
skb_put(precvbuf->pskb, purb->actual_length);
skb_queue_tail(&precvpriv->rx_skb_queue, precvbuf->pskb);
#ifndef CONFIG_FIX_NR_BULKIN_BUFFER
if (skb_queue_len(&precvpriv->rx_skb_queue)<=1)
#endif
tasklet_schedule(&precvpriv->recv_tasklet);
precvbuf->pskb = NULL;
rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
}
}
else
{
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete : purb->status(%d) != 0 \n", purb->status));
DBG_8192C("###=> usb_read_port_complete => urb status(%d)\n", purb->status);
if(rtw_inc_and_chk_continual_io_error(adapter_to_dvobj(padapter)) == _TRUE ){
padapter->bSurpriseRemoved = _TRUE;
}
switch(purb->status) {
case -EINVAL:
case -EPIPE:
case -ENODEV:
case -ESHUTDOWN:
//padapter->bSurpriseRemoved=_TRUE;
//RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bSurpriseRemoved=TRUE\n"));
case -ENOENT:
padapter->bDriverStopped=_TRUE;
RT_TRACE(_module_hci_ops_os_c_,_drv_err_,("usb_read_port_complete:bDriverStopped=TRUE\n"));
break;
case -EPROTO:
case -EILSEQ:
case -ETIME:
case -ECOMM:
case -EOVERFLOW:
#ifdef DBG_CONFIG_ERROR_DETECT
{
HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
pHalData->srestpriv.Wifi_Error_Status = USB_READ_PORT_FAIL;
}
#endif
rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
break;
case -EINPROGRESS:
DBG_8192C("ERROR: URB IS IN PROGRESS!/n");
break;
default:
break;
}
}
exit:
_func_exit_;
}
开发者ID:rmbq,项目名称:rtl8812au,代码行数:91,代码来源:usb_ops_linux.c
示例11: ctcm_transmit_skb
/**
* Transmit a packet.
* This is a helper function for ctcm_tx().
*
* ch Channel to be used for sending.
* skb Pointer to struct sk_buff of packet to send.
* The linklevel header has already been set up
* by ctcm_tx().
*
* returns 0 on success, -ERRNO on failure. (Never fails.)
*/
static int ctcm_transmit_skb(struct channel *ch, struct sk_buff *skb)
{
unsigned long saveflags;
struct ll_header header;
int rc = 0;
__u16 block_len;
int ccw_idx;
struct sk_buff *nskb;
unsigned long hi;
/* we need to acquire the lock for testing the state
* otherwise we can have an IRQ changing the state to
* TXIDLE after the test but before acquiring the lock.
*/
spin_lock_irqsave(&ch->collect_lock, saveflags);
if (fsm_getstate(ch->fsm) != CTC_STATE_TXIDLE) {
int l = skb->len + LL_HEADER_LENGTH;
if (ch->collect_len + l > ch->max_bufsize - 2) {
spin_unlock_irqrestore(&ch->collect_lock, saveflags);
return -EBUSY;
} else {
atomic_inc(&skb->users);
header.length = l;
header.type = skb->protocol;
header.unused = 0;
memcpy(skb_push(skb, LL_HEADER_LENGTH), &header,
LL_HEADER_LENGTH);
skb_queue_tail(&ch->collect_queue, skb);
ch->collect_len += l;
}
spin_unlock_irqrestore(&ch->collect_lock, saveflags);
goto done;
}
spin_unlock_irqrestore(&ch->collect_lock, saveflags);
/*
* Protect skb against beeing free'd by upper
* layers.
*/
atomic_inc(&skb->users);
ch->prof.txlen += skb->len;
header.length = skb->len + LL_HEADER_LENGTH;
header.type = skb->protocol;
header.unused = 0;
memcpy(skb_push(skb, LL_HEADER_LENGTH), &header, LL_HEADER_LENGTH);
block_len = skb->len + 2;
*((__u16 *)skb_push(skb, 2)) = block_len;
/*
* IDAL support in CTCM is broken, so we have to
* care about skb's above 2G ourselves.
*/
hi = ((unsigned long)skb_tail_pointer(skb) + LL_HEADER_LENGTH) >> 31;
if (hi) {
nskb = alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
if (!nskb) {
atomic_dec(&skb->users);
skb_pull(skb, LL_HEADER_LENGTH + 2);
ctcm_clear_busy(ch->netdev);
return -ENOMEM;
} else {
memcpy(skb_put(nskb, skb->len), skb->data, skb->len);
atomic_inc(&nskb->users);
atomic_dec(&skb->users);
dev_kfree_skb_irq(skb);
skb = nskb;
}
}
ch->ccw[4].count = block_len;
if (set_normalized_cda(&ch->ccw[4], skb->data)) {
/*
* idal allocation failed, try via copying to
* trans_skb. trans_skb usually has a pre-allocated
* idal.
*/
if (ctcm_checkalloc_buffer(ch)) {
/*
* Remove our header. It gets added
* again on retransmit.
*/
atomic_dec(&skb->users);
skb_pull(skb, LL_HEADER_LENGTH + 2);
ctcm_clear_busy(ch->netdev);
return -ENOMEM;
}
skb_reset_tail_pointer(ch->trans_skb);
ch->trans_skb->len = 0;
//.........这里部分代码省略.........
开发者ID:ARMWorks,项目名称:FA_2451_Linux_Kernel,代码行数:101,代码来源:ctcm_main.c
示例12: rx_complete
static void rx_complete(struct usb_ep *ep, struct usb_request *req)
{
struct sk_buff *skb = req->context;
struct eth_dev *dev = ep->driver_data;
int status = req->status;
bool queue = 0;
switch (status) {
/* normal completion */
case 0:
skb_put(skb, req->actual);
if (dev->unwrap) {
unsigned long flags;
spin_lock_irqsave(&dev->lock, flags);
if (dev->port_usb) {
status = dev->unwrap(dev->port_usb,
skb,
&dev->rx_frames);
if (status == -EINVAL)
dev->net->stats.rx_errors++;
else if (status == -EOVERFLOW)
dev->net->stats.rx_over_errors++;
} else {
dev_kfree_skb_any(skb);
status = -ENOTCONN;
}
spin_unlock_irqrestore(&dev->lock, flags);
} else {
skb_queue_tail(&dev->rx_frames, skb);
}
if (!status)
queue = 1;
break;
/* software-driven interface shutdown */
case -ECONNRESET: /* unlink */
case -ESHUTDOWN: /* disconnect etc */
VDBG(dev, "rx shutdown, code %d\n", status);
goto quiesce;
/* for hardware automagic (such as pxa) */
case -ECONNABORTED: /* endpoint reset */
DBG(dev, "rx %s reset\n", ep->name);
defer_kevent(dev, WORK_RX_MEMORY);
quiesce:
dev_kfree_skb_any(skb);
goto clean;
/* data overrun */
case -EOVERFLOW:
dev->net->stats.rx_over_errors++;
/* FALLTHROUGH */
default:
queue = 1;
dev_kfree_skb_any(skb);
dev->net->stats.rx_errors++;
DBG(dev, "rx status %d\n", status);
break;
}
clean:
spin_lock(&dev->req_lock);
list_add(&req->list, &dev->rx_reqs);
spin_unlock(&dev->req_lock);
if (queue)
queue_work(uether_wq, &dev->rx_work);
}
开发者ID:Arunvasu,项目名称:taoshan,代码行数:73,代码来源:u_ether.c
示例13: ctcmpc_send_sweep_req
static void ctcmpc_send_sweep_req(struct channel *rch)
{
struct net_device *dev = rch->netdev;
struct ctcm_priv *priv;
struct mpc_group *grp;
struct th_sweep *header;
struct sk_buff *sweep_skb;
struct channel *ch;
/* int rc = 0; */
priv = dev->ml_priv;
grp = priv->mpcg;
ch = priv->channel[CTCM_WRITE];
/* sweep processing is not complete until response and request */
/* has completed for all read channels in group */
if (grp->in_sweep == 0) {
grp->in_sweep = 1;
grp->sweep_rsp_pend_num = grp->active_channels[CTCM_READ];
grp->sweep_req_pend_num = grp->active_channels[CTCM_READ];
}
sweep_skb = __dev_alloc_skb(MPC_BUFSIZE_DEFAULT, GFP_ATOMIC|GFP_DMA);
if (sweep_skb == NULL) {
/* rc = -ENOMEM; */
goto nomem;
}
header = kmalloc(TH_SWEEP_LENGTH, gfp_type());
if (!header) {
dev_kfree_skb_any(sweep_skb);
/* rc = -ENOMEM; */
goto nomem;
}
header->th.th_seg = 0x00 ;
header->th.th_ch_flag = TH_SWEEP_REQ; /* 0x0f */
header->th.th_blk_flag = 0x00;
header->th.th_is_xid = 0x00;
header->th.th_seq_num = 0x00;
header->sw.th_last_seq = ch->th_seq_num;
memcpy(skb_put(sweep_skb, TH_SWEEP_LENGTH), header, TH_SWEEP_LENGTH);
kfree(header);
dev->trans_start = jiffies;
skb_queue_tail(&ch->sweep_queue, sweep_skb);
fsm_addtimer(&ch->sweep_timer, 100, CTC_EVENT_RSWEEP_TIMER, ch);
return;
nomem:
grp->in_sweep = 0;
ctcm_clear_busy(dev);
fsm_event(grp->fsm, MPCG_EVENT_INOP, dev);
return;
}
开发者ID:ARMWorks,项目名称:FA_2451_Linux_Kernel,代码行数:62,代码来源:ctcm_main.c
示例14: qpolicy_simple_push
static void qpolicy_simple_push(struct sock *sk, struct sk_buff *skb)
{
skb_queue_tail(&sk->sk_write_queue, skb);
}
开发者ID:romanbb,项目名称:android_kernel_lge_d851,代码行数:4,代码来源:qpolicy.c
示例15: hci_sock_sendmsg
static int hci_sock_sendmsg(struct socket *sock, struct msghdr *msg, int len,
struct scm_cookie *scm)
{
struct sock *sk = sock->sk;
struct hci_dev *hdev;
struct sk_buff *skb;
int err;
BT_DBG("sock %p sk %p", sock, sk);
if (msg->msg_flags & MSG_OOB)
return -EOPNOTSUPP;
if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_NOSIGNAL|MSG_ERRQUEUE))
return -EINVAL;
if (len < 4)
return -EINVAL;
lock_sock(sk);
if (!(hdev = hci_pi(sk)->hdev)) {
err = -EBADFD;
goto done;
}
if (!(skb = bluez_skb_send_alloc(sk, len, msg->msg_flags & MSG_DONTWAIT, &err)))
goto done;
if (memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len)) {
err = -EFAULT;
goto drop;
}
skb->pkt_type = *((unsigned char *) skb->data);
skb_pull(skb, 1);
skb->dev = (void *) hdev;
if (skb->pkt_type == HCI_COMMAND_PKT) {
u16 opcode = __le16_to_cpu(get_unaligned((u16 *)skb->data));
u16 ogf = cmd_opcode_ogf(opcode);
u16 ocf = cmd_opcode_ocf(opcode);
if (((ogf > HCI_SFLT_MAX_OGF) ||
!hci_test_bit(ocf & HCI_FLT_OCF_BITS, &hci_sec_filter.ocf_mask[ogf])) &&
!capable(CAP_NET_RAW)) {
err = -EPERM;
goto drop;
}
if (test_bit(HCI_RAW, &hdev->flags) || (ogf == OGF_VENDOR_CMD)) {
skb_queue_tail(&hdev->raw_q, skb);
hci_sched_tx(hdev);
} else {
skb_queue_tail(&hdev->cmd_q, skb);
hci_sched_cmd(hdev);
}
} else {
if (!capable(CAP_NET_RAW)) {
err = -EPERM;
goto drop;
}
skb_queue_tail(&hdev->raw_q, skb);
hci_sched_tx(hdev);
}
err = len;
done:
release_sock(sk);
return err;
drop:
kfree_skb(skb);
goto done;
}
开发者ID:jameshilliard,项目名称:actiontec_opensrc_mi424wr-rev-e-f_fw-20-10-7-5,代码行数:77,代码来源:hci_sock.c
示例16: nr_state3_machine
/*
* State machine for state 3, Connected State.
* The handling of the timer(s) is in file nr_timer.c
* Handling of state 0 and connection release is in netrom.c.
*/
static int nr_state3_machine(struct sock *sk, struct sk_buff *skb, int frametype)
{
struct sk_buff_head temp_queue;
struct sk_buff *skbn;
unsigned short save_vr;
unsigned short nr, ns;
int queued = 0;
nr = skb->data[18];
ns = skb->data[17];
switch (frametype) {
case NR_CONNREQ:
nr_write_internal(sk, NR_CONNACK);
break;
case NR_DISCREQ:
nr_write_internal(sk, NR_DISCACK);
nr_disconnect(sk, 0);
break;
case NR_CONNACK | NR_CHOKE_FLAG:
case NR_DISCACK:
nr_disconnect(sk, ECONNRESET);
break;
case NR_INFOACK:
case NR_INFOACK | NR_CHOKE_FLAG:
case NR_INFOACK | NR_NAK_FLAG:
case NR_INFOACK | NR_NAK_FLAG | NR_CHOKE_FLAG:
if (frametype & NR_CHOKE_FLAG) {
sk->protinfo.nr->condition |= NR_COND_PEER_RX_BUSY;
nr_start_t4timer(sk);
} else {
sk->protinfo.nr->condition &= ~NR_COND_PEER_RX_BUSY;
nr_stop_t4timer(sk);
}
if (!nr_validate_nr(sk, nr)) {
break;
}
if (frametype & NR_NAK_FLAG) {
nr_frames_acked(sk, nr);
nr_send_nak_frame(sk);
} else {
if (sk->protinfo.nr->condition & NR_COND_PEER_RX_BUSY) {
nr_frames_acked(sk, nr);
} else {
nr_check_iframes_acked(sk, nr);
}
}
break;
case NR_INFO:
case NR_INFO | NR_NAK_FLAG:
case NR_INFO | NR_CHOKE_FLAG:
case NR_INFO | NR_MORE_FLAG:
case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG:
case NR_INFO | NR_CHOKE_FLAG | NR_MORE_FLAG:
case NR_INFO | NR_NAK_FLAG | NR_MORE_FLAG:
case NR_INFO | NR_NAK_FLAG | NR_CHOKE_FLAG | NR_MORE_FLAG:
if (frametype & NR_CHOKE_FLAG) {
sk->protinfo.nr->condition |= NR_COND_PEER_RX_BUSY;
nr_start_t4timer(sk);
} else {
sk->protinfo.nr->condition &= ~NR_COND_PEER_RX_BUSY;
nr_stop_t4timer(sk);
}
if (nr_validate_nr(sk, nr)) {
if (frametype & NR_NAK_FLAG) {
nr_frames_acked(sk, nr);
nr_send_nak_frame(sk);
} else {
if (sk->protinfo.nr->condition & NR_COND_PEER_RX_BUSY) {
nr_frames_acked(sk, nr);
} else {
nr_check_iframes_acked(sk, nr);
}
}
}
queued = 1;
skb_queue_head(&sk->protinfo.nr->reseq_queue, skb);
if (sk->protinfo.nr->condition & NR_COND_OWN_RX_BUSY)
break;
skb_queue_head_init(&temp_queue);
do {
save_vr = sk->protinfo.nr->vr;
while ((skbn = skb_dequeue(&sk->protinfo.nr->reseq_queue)) != NULL) {
ns = skbn->data[17];
if (ns == sk->protinfo.nr->vr) {
if (nr_queue_rx_frame(sk, skbn, frametype & NR_MORE_FLAG) == 0) {
sk->protinfo.nr->vr = (sk->protinfo.nr->vr + 1) % NR_MODULUS;
} else {
sk->protinfo.nr->condition |= NR_COND_OWN_RX_BUSY;
skb_queue_tail(&temp_queue, skbn);
//.........这里部分代码省略.........
开发者ID:JBTech,项目名称:ralink_rt5350,代码行数:101,代码来源:nr_in.c
示例17: mwifiex_usb_aggr_tx_data
/* This function prepare data packet to be send under usb tx aggregation
* protocol, check current usb aggregation status, link packet to aggrgation
* list if possible, work flow as below:
* (1) if only 1 packet available, add usb tx aggregation header and send.
* (2) if packet is able to aggregated, link it to current aggregation list.
* (3) if packet is not able to aggregated, aggregate and send exist packets
* in aggrgation list. Then, link packet in the list if there is more
* packet in transmit queue, otherwise try to transmit single packet.
*/
static int mwifiex_usb_aggr_tx_data(struct mwifiex_adapter *adapter, u8 ep,
struct sk_buff *skb,
struct mwifiex_tx_param *tx_param,
struct usb_tx_data_port *port)
{
u8 *payload, pad;
u16 align = adapter->bus_aggr.tx_aggr_align;
struct sk_buff *skb_send = NULL;
struct urb_context *context = NULL;
struct txpd *local_tx_pd =
(struct txpd *)((u8 *)skb->data + adapter->intf_hdr_len);
u8 f_send_aggr_buf = 0;
u8 f_send_cur_buf = 0;
u8 f_precopy_cur_buf = 0;
u8 f_postcopy_cur_buf = 0;
u32 timeout;
int ret;
/* padding to ensure each packet alginment */
pad = (align - (skb->len & (align - 1))) % align;
if (tx_param && tx_param->next_pkt_len) {
/* next packet available in tx queue*/
if (port->tx_aggr.aggr_len + skb->len + pad >
adapter->bus_aggr.tx_aggr_max_size) {
f_send_aggr_buf = 1;
f_postcopy_cur_buf = 1;
} else {
/* current packet could be aggregated*/
f_precopy
|
请发表评论