Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 361082
b: refs/heads/master
c: 930df2d
h: refs/heads/master
v: v3
  • Loading branch information
David S. Miller committed Mar 6, 2013
1 parent 7ec6a19 commit a44fd67
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 32cdd592b723fc88ecca699e550197cd48bb4ad6
refs/heads/master: 930df2dfc7073c9ed2d0b47a08e47027ae83c545
77 changes: 77 additions & 0 deletions trunk/Documentation/networking/tuntap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,83 @@ Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
Proto [2 bytes]
Raw protocol(IP, IPv6, etc) frame.

3.3 Multiqueue tuntap interface:

From version 3.8, Linux supports multiqueue tuntap which can uses multiple
file descriptors (queues) to parallelize packets sending or receiving. The
device allocation is the same as before, and if user wants to create multiple
queues, TUNSETIFF with the same device name must be called many times with
IFF_MULTI_QUEUE flag.

char *dev should be the name of the device, queues is the number of queues to
be created, fds is used to store and return the file descriptors (queues)
created to the caller. Each file descriptor were served as the interface of a
queue which could be accessed by userspace.

#include <linux/if.h>
#include <linux/if_tun.h>

int tun_alloc_mq(char *dev, int queues, int *fds)
{
struct ifreq ifr;
int fd, err, i;

if (!dev)
return -1;

memset(&ifr, 0, sizeof(ifr));
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_TAP - TAP device
*
* IFF_NO_PI - Do not provide packet information
* IFF_MULTI_QUEUE - Create a queue of multiqueue device
*/
ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE;
strcpy(ifr.ifr_name, dev);

for (i = 0; i < queues; i++) {
if ((fd = open("/dev/net/tun", O_RDWR)) < 0)
goto err;
err = ioctl(fd, TUNSETIFF, (void *)&ifr);
if (err) {
close(fd);
goto err;
}
fds[i] = fd;
}

return 0;
err:
for (--i; i >= 0; i--)
close(fds[i]);
return err;
}

A new ioctl(TUNSETQUEUE) were introduced to enable or disable a queue. When
calling it with IFF_DETACH_QUEUE flag, the queue were disabled. And when
calling it with IFF_ATTACH_QUEUE flag, the queue were enabled. The queue were
enabled by default after it was created through TUNSETIFF.

fd is the file descriptor (queue) that we want to enable or disable, when
enable is true we enable it, otherwise we disable it

#include <linux/if.h>
#include <linux/if_tun.h>

int tun_set_queue(int fd, int enable)
{
struct ifreq ifr;

memset(&ifr, 0, sizeof(ifr));

if (enable)
ifr.ifr_flags = IFF_ATTACH_QUEUE;
else
ifr.ifr_flags = IFF_DETACH_QUEUE;

return ioctl(fd, TUNSETQUEUE, (void *)&ifr);
}

Universal TUN/TAP device driver Frequently Asked Question.

1. What platforms are supported by TUN/TAP driver ?
Expand Down
1 change: 1 addition & 0 deletions trunk/drivers/net/ethernet/emulex/benet/be.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ struct be_adapter {
struct pci_dev *pdev;
struct net_device *netdev;

u8 __iomem *csr; /* CSR BAR used only for BE2/3 */
u8 __iomem *db; /* Door Bell */

struct mutex mbox_lock; /* For serializing mbox cmds to BE card */
Expand Down
15 changes: 9 additions & 6 deletions trunk/drivers/net/ethernet/emulex/benet/be_cmds.c
Original file line number Diff line number Diff line change
Expand Up @@ -473,14 +473,17 @@ static int be_mbox_notify_wait(struct be_adapter *adapter)
return 0;
}

static void be_POST_stage_get(struct be_adapter *adapter, u16 *stage)
static u16 be_POST_stage_get(struct be_adapter *adapter)
{
u32 sem;
u32 reg = skyhawk_chip(adapter) ? SLIPORT_SEMAPHORE_OFFSET_SH :
SLIPORT_SEMAPHORE_OFFSET_BE;

pci_read_config_dword(adapter->pdev, reg, &sem);
*stage = sem & POST_STAGE_MASK;
if (BEx_chip(adapter))
sem = ioread32(adapter->csr + SLIPORT_SEMAPHORE_OFFSET_BEx);
else
pci_read_config_dword(adapter->pdev,
SLIPORT_SEMAPHORE_OFFSET_SH, &sem);

return sem & POST_STAGE_MASK;
}

int lancer_wait_ready(struct be_adapter *adapter)
Expand Down Expand Up @@ -574,7 +577,7 @@ int be_fw_wait_ready(struct be_adapter *adapter)
}

do {
be_POST_stage_get(adapter, &stage);
stage = be_POST_stage_get(adapter);
if (stage == POST_STAGE_ARMFW_RDY)
return 0;

Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/net/ethernet/emulex/benet/be_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
#define MPU_EP_CONTROL 0

/********** MPU semphore: used for SH & BE *************/
#define SLIPORT_SEMAPHORE_OFFSET_BE 0x7c
#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94
#define SLIPORT_SEMAPHORE_OFFSET_BEx 0xac /* CSR BAR offset */
#define SLIPORT_SEMAPHORE_OFFSET_SH 0x94 /* PCI-CFG offset */
#define POST_STAGE_MASK 0x0000FFFF
#define POST_ERR_MASK 0x1
#define POST_ERR_SHIFT 31
Expand Down
10 changes: 10 additions & 0 deletions trunk/drivers/net/ethernet/emulex/benet/be_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3688,6 +3688,8 @@ static void be_netdev_init(struct net_device *netdev)

static void be_unmap_pci_bars(struct be_adapter *adapter)
{
if (adapter->csr)
pci_iounmap(adapter->pdev, adapter->csr);
if (adapter->db)
pci_iounmap(adapter->pdev, adapter->db);
}
Expand Down Expand Up @@ -3721,6 +3723,12 @@ static int be_map_pci_bars(struct be_adapter *adapter)
adapter->if_type = (sli_intf & SLI_INTF_IF_TYPE_MASK) >>
SLI_INTF_IF_TYPE_SHIFT;

if (BEx_chip(adapter) && be_physfn(adapter)) {
adapter->csr = pci_iomap(adapter->pdev, 2, 0);
if (adapter->csr == NULL)
return -ENOMEM;
}

addr = pci_iomap(adapter->pdev, db_bar(adapter), 0);
if (addr == NULL)
goto pci_map_err;
Expand Down Expand Up @@ -4329,6 +4337,8 @@ static pci_ers_result_t be_eeh_reset(struct pci_dev *pdev)
pci_restore_state(pdev);

/* Check if card is ok and fw is ready */
dev_info(&adapter->pdev->dev,
"Waiting for FW to be ready after EEH reset\n");
status = be_fw_wait_ready(adapter);
if (status)
return PCI_ERS_RESULT_DISCONNECT;
Expand Down
4 changes: 2 additions & 2 deletions trunk/drivers/net/ethernet/sfc/efx.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,9 @@ static inline void efx_device_detach_sync(struct efx_nic *efx)
* TX scheduler is stopped when we're done and before
* netif_device_present() becomes false.
*/
netif_tx_lock(dev);
netif_tx_lock_bh(dev);
netif_device_detach(dev);
netif_tx_unlock(dev);
netif_tx_unlock_bh(dev);
}

#endif /* EFX_EFX_H */
2 changes: 1 addition & 1 deletion trunk/drivers/net/ethernet/sfc/rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ static int efx_init_rx_buffers_page(struct efx_rx_queue *rx_queue)
rx_buf = efx_rx_buffer(rx_queue, index);
rx_buf->dma_addr = dma_addr + EFX_PAGE_IP_ALIGN;
rx_buf->u.page = page;
rx_buf->page_offset = page_offset;
rx_buf->page_offset = page_offset + EFX_PAGE_IP_ALIGN;
rx_buf->len = efx->rx_buffer_len - EFX_PAGE_IP_ALIGN;
rx_buf->flags = EFX_RX_BUF_PAGE;
++rx_queue->added_count;
Expand Down

0 comments on commit a44fd67

Please sign in to comment.