Lines Matching +full:frame +full:- +full:buffer

16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
49 display_buffer(char *buffer, int length) in display_buffer() argument
55 printk("[%02x]", *buffer & 255); in display_buffer()
56 length--; in display_buffer()
57 buffer++; in display_buffer()
69 * Helper function to create a PIMFOR management frame header.
74 h->version = PIMFOR_VERSION; in pimfor_encode_header()
75 h->operation = operation; in pimfor_encode_header()
76 h->device_id = PIMFOR_DEV_ID_MHLI_MIB; in pimfor_encode_header()
77 h->flags = 0; in pimfor_encode_header()
78 h->oid = cpu_to_be32(oid); in pimfor_encode_header()
79 h->length = cpu_to_be32(length); in pimfor_encode_header()
83 * Helper function to analyze a PIMFOR management frame header.
91 if (h->flags & PIMFOR_FLAG_LITTLE_ENDIAN) { in pimfor_decode_header()
92 le32_to_cpus(&h->oid); in pimfor_decode_header()
93 le32_to_cpus(&h->length); in pimfor_decode_header()
95 be32_to_cpus(&h->oid); in pimfor_decode_header()
96 be32_to_cpus(&h->length); in pimfor_decode_header()
98 if (h->oid != OID_INL_TUNNEL) in pimfor_decode_header()
113 (isl38xx_control_block *) priv->control_block; in islpci_mgmt_rx_fill()
114 u32 curr = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ]); in islpci_mgmt_rx_fill()
120 while (curr - priv->index_mgmt_rx < ISL38XX_CB_MGMT_QSIZE) { in islpci_mgmt_rx_fill()
122 struct islpci_membuf *buf = &priv->mgmt_rx[index]; in islpci_mgmt_rx_fill()
123 isl38xx_fragment *frag = &cb->rx_data_mgmt[index]; in islpci_mgmt_rx_fill()
125 if (buf->mem == NULL) { in islpci_mgmt_rx_fill()
126 buf->mem = kmalloc(MGMT_FRAME_SIZE, GFP_ATOMIC); in islpci_mgmt_rx_fill()
127 if (!buf->mem) { in islpci_mgmt_rx_fill()
129 "Error allocating management frame.\n"); in islpci_mgmt_rx_fill()
130 return -ENOMEM; in islpci_mgmt_rx_fill()
132 buf->size = MGMT_FRAME_SIZE; in islpci_mgmt_rx_fill()
134 if (buf->pci_addr == 0) { in islpci_mgmt_rx_fill()
135 buf->pci_addr = pci_map_single(priv->pdev, buf->mem, in islpci_mgmt_rx_fill()
138 if (!buf->pci_addr) { in islpci_mgmt_rx_fill()
141 return -ENOMEM; in islpci_mgmt_rx_fill()
146 frag->size = cpu_to_le16(MGMT_FRAME_SIZE); in islpci_mgmt_rx_fill()
147 frag->flags = 0; in islpci_mgmt_rx_fill()
148 frag->address = cpu_to_le32(buf->pci_addr); in islpci_mgmt_rx_fill()
152 * been written before announcing the frame buffer to in islpci_mgmt_rx_fill()
155 cb->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] = cpu_to_le32(curr); in islpci_mgmt_rx_fill()
161 * Create and transmit a management frame using "operation" and "oid",
163 * We either return an error and free the frame, or we return 0 and
164 * islpci_mgt_cleanup_transmit() frees the frame in the tx-done
173 (isl38xx_control_block *) priv->control_block; in islpci_mgt_transmit()
175 int err = -EINVAL; in islpci_mgt_transmit()
188 printk(KERN_DEBUG "%s: mgmt frame too large %d\n", in islpci_mgt_transmit()
189 ndev->name, frag_len); in islpci_mgt_transmit()
193 err = -ENOMEM; in islpci_mgt_transmit()
196 printk(KERN_DEBUG "%s: cannot allocate mgmt frame\n", in islpci_mgt_transmit()
197 ndev->name); in islpci_mgt_transmit()
216 h->operation, oid, h->device_id, h->flags, length); in islpci_mgt_transmit()
218 /* display the buffer contents for debugging */ in islpci_mgt_transmit()
224 err = -ENOMEM; in islpci_mgt_transmit()
225 buf.pci_addr = pci_map_single(priv->pdev, buf.mem, frag_len, in islpci_mgt_transmit()
229 ndev->name); in islpci_mgt_transmit()
234 spin_lock_irqsave(&priv->slock, flags); in islpci_mgt_transmit()
235 curr_frag = le32_to_cpu(cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ]); in islpci_mgt_transmit()
236 if (curr_frag - priv->index_mgmt_tx >= ISL38XX_CB_MGMT_QSIZE) { in islpci_mgt_transmit()
238 ndev->name); in islpci_mgt_transmit()
242 /* commit the frame to the tx device queue */ in islpci_mgt_transmit()
244 priv->mgmt_tx[index] = buf; in islpci_mgt_transmit()
245 frag = &cb->tx_data_mgmt[index]; in islpci_mgt_transmit()
246 frag->size = cpu_to_le16(frag_len); in islpci_mgt_transmit()
247 frag->flags = 0; /* for any other than the last fragment, set to 1 */ in islpci_mgt_transmit()
248 frag->address = cpu_to_le32(buf.pci_addr); in islpci_mgt_transmit()
251 * been written before announcing the frame buffer to in islpci_mgt_transmit()
254 cb->driver_curr_frag[ISL38XX_CB_TX_MGMTQ] = cpu_to_le32(curr_frag + 1); in islpci_mgt_transmit()
255 spin_unlock_irqrestore(&priv->slock, flags); in islpci_mgt_transmit()
262 spin_unlock_irqrestore(&priv->slock, flags); in islpci_mgt_transmit()
270 * Receive a management frame from the device.
272 * frame for a previous request sent via islpci_mgt_transmit().
279 (isl38xx_control_block *) priv->control_block; in islpci_mgt_receive()
289 curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_RX_MGMTQ]); in islpci_mgt_receive()
292 for (; priv->index_mgmt_rx < curr_frag; priv->index_mgmt_rx++) { in islpci_mgt_receive()
294 u32 index = priv->index_mgmt_rx % ISL38XX_CB_MGMT_QSIZE; in islpci_mgt_receive()
295 struct islpci_membuf *buf = &priv->mgmt_rx[index]; in islpci_mgt_receive()
298 struct islpci_mgmtframe *frame; in islpci_mgt_receive() local
301 * is possible. Drop the frame, reuse the buffer. */ in islpci_mgt_receive()
302 if (le16_to_cpu(cb->rx_data_mgmt[index].flags) != 0) { in islpci_mgt_receive()
304 ndev->name, in islpci_mgt_receive()
305 le16_to_cpu(cb->rx_data_mgmt[index].flags)); in islpci_mgt_receive()
310 frag_len = le16_to_cpu(cb->rx_data_mgmt[index].size); in islpci_mgt_receive()
314 * size of a receive buffer. Thus, if this check in islpci_mgt_receive()
319 ndev->name, frag_len, frag_len); in islpci_mgt_receive()
324 pci_dma_sync_single_for_cpu(priv->pdev, buf->pci_addr, in islpci_mgt_receive()
325 buf->size, PCI_DMA_FROMDEVICE); in islpci_mgt_receive()
327 /* Perform endianess conversion for PIMFOR header in-place. */ in islpci_mgt_receive()
328 header = pimfor_decode_header(buf->mem, frag_len); in islpci_mgt_receive()
331 ndev->name); in islpci_mgt_receive()
338 header->device_id = priv->ndev->ifindex; in islpci_mgt_receive()
343 header->operation, header->oid, header->device_id, in islpci_mgt_receive()
344 header->flags, header->length); in islpci_mgt_receive()
346 /* display the buffer contents for debugging */ in islpci_mgt_receive()
349 header->length); in islpci_mgt_receive()
353 if (header->flags & PIMFOR_FLAG_APPLIC_ORIGIN) { in islpci_mgt_receive()
355 "%s: errant PIMFOR application frame\n", in islpci_mgt_receive()
356 ndev->name); in islpci_mgt_receive()
360 /* Determine frame size, skipping OID_INL_TUNNEL headers. */ in islpci_mgt_receive()
361 size = PIMFOR_HEADER_SIZE + header->length; in islpci_mgt_receive()
362 frame = kmalloc(sizeof (struct islpci_mgmtframe) + size, in islpci_mgt_receive()
364 if (!frame) { in islpci_mgt_receive()
367 ndev->name, header->oid); in islpci_mgt_receive()
370 frame->ndev = ndev; in islpci_mgt_receive()
371 memcpy(&frame->buf, header, size); in islpci_mgt_receive()
372 frame->header = (pimfor_header_t *) frame->buf; in islpci_mgt_receive()
373 frame->data = frame->buf + PIMFOR_HEADER_SIZE; in islpci_mgt_receive()
377 "frame: header: %p, data: %p, size: %d\n", in islpci_mgt_receive()
378 frame->header, frame->data, size); in islpci_mgt_receive()
381 if (header->operation == PIMFOR_OP_TRAP) { in islpci_mgt_receive()
385 header->oid, header->device_id, header->flags, in islpci_mgt_receive()
386 header->length); in islpci_mgt_receive()
391 INIT_WORK(&frame->ws, prism54_process_trap); in islpci_mgt_receive()
392 schedule_work(&frame->ws); in islpci_mgt_receive()
397 if ((frame = xchg(&priv->mgmt_received, frame)) != NULL) { in islpci_mgt_receive()
400 ndev->name); in islpci_mgt_receive()
401 kfree(frame); in islpci_mgt_receive()
406 wake_up(&priv->mgmt_wqueue); in islpci_mgt_receive()
422 (isl38xx_control_block *) priv->control_block; in islpci_mgt_cleanup_transmit()
433 curr_frag = le32_to_cpu(cb->device_curr_frag[ISL38XX_CB_TX_MGMTQ]); in islpci_mgt_cleanup_transmit()
436 for (; priv->index_mgmt_tx < curr_frag; priv->index_mgmt_tx++) { in islpci_mgt_cleanup_transmit()
437 int index = priv->index_mgmt_tx % ISL38XX_CB_MGMT_QSIZE; in islpci_mgt_cleanup_transmit()
438 struct islpci_membuf *buf = &priv->mgmt_tx[index]; in islpci_mgt_cleanup_transmit()
439 pci_unmap_single(priv->pdev, buf->pci_addr, buf->size, in islpci_mgt_cleanup_transmit()
441 buf->pci_addr = 0; in islpci_mgt_cleanup_transmit()
442 kfree(buf->mem); in islpci_mgt_cleanup_transmit()
443 buf->mem = NULL; in islpci_mgt_cleanup_transmit()
444 buf->size = 0; in islpci_mgt_cleanup_transmit()
449 * Perform one request-response transaction to the device.
465 if (mutex_lock_interruptible(&priv->mgmt_lock)) in islpci_mgt_transaction()
466 return -ERESTARTSYS; in islpci_mgt_transaction()
468 prepare_to_wait(&priv->mgmt_wqueue, &wait, TASK_UNINTERRUPTIBLE); in islpci_mgt_transaction()
473 err = -ETIMEDOUT; in islpci_mgt_transaction()
476 struct islpci_mgmtframe *frame; in islpci_mgt_transaction() local
479 frame = xchg(&priv->mgmt_received, NULL); in islpci_mgt_transaction()
480 if (frame) { in islpci_mgt_transaction()
481 if (frame->header->oid == oid) { in islpci_mgt_transaction()
482 *recvframe = frame; in islpci_mgt_transaction()
488 ndev->name, (unsigned int) oid, in islpci_mgt_transaction()
489 frame->header->oid); in islpci_mgt_transaction()
490 kfree(frame); in islpci_mgt_transaction()
491 frame = NULL; in islpci_mgt_transaction()
498 ndev->name, timeout_left); in islpci_mgt_transaction()
501 timeout_left += timeleft - wait_cycle_jiffies; in islpci_mgt_transaction()
504 ndev->name); in islpci_mgt_transaction()
508 finish_wait(&priv->mgmt_wqueue, &wait); in islpci_mgt_transaction()
509 mutex_unlock(&priv->mgmt_lock); in islpci_mgt_transaction()