Merge HEAD from master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6.git
This commit is contained in:
commit
826509f811
|
@ -135,3 +135,15 @@ Why: With the 16-bit PCMCIA subsystem now behaving (almost) like a
|
|||
pcmciautils package available at
|
||||
http://kernel.org/pub/linux/utils/kernel/pcmcia/
|
||||
Who: Dominik Brodowski <linux@brodo.de>
|
||||
|
||||
---------------------------
|
||||
|
||||
What: ip_queue and ip6_queue (old ipv4-only and ipv6-only netfilter queue)
|
||||
When: December 2005
|
||||
Why: This interface has been obsoleted by the new layer3-independent
|
||||
"nfnetlink_queue". The Kernel interface is compatible, so the old
|
||||
ip[6]tables "QUEUE" targets still work and will transparently handle
|
||||
all packets into nfnetlink queue number 0. Userspace users will have
|
||||
to link against API-compatible library on top of libnfnetlink_queue
|
||||
instead of the current 'libipq'.
|
||||
Who: Harald Welte <laforge@netfilter.org>
|
||||
|
|
|
@ -513,7 +513,7 @@ static void rx_complete (amb_dev * dev, rx_out * rx) {
|
|||
|
||||
// VC layer stats
|
||||
atomic_inc(&atm_vcc->stats->rx);
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
// end of our responsability
|
||||
atm_vcc->push (atm_vcc, skb);
|
||||
return;
|
||||
|
|
|
@ -325,7 +325,7 @@ static int atmtcp_c_send(struct atm_vcc *vcc,struct sk_buff *skb)
|
|||
result = -ENOBUFS;
|
||||
goto done;
|
||||
}
|
||||
do_gettimeofday(&new_skb->stamp);
|
||||
__net_timestamp(new_skb);
|
||||
memcpy(skb_put(new_skb,skb->len),skb->data,skb->len);
|
||||
out_vcc->push(out_vcc,new_skb);
|
||||
atomic_inc(&vcc->stats->tx);
|
||||
|
|
|
@ -537,7 +537,7 @@ static int rx_aal0(struct atm_vcc *vcc)
|
|||
return 0;
|
||||
}
|
||||
skb_put(skb,length);
|
||||
skb->stamp = eni_vcc->timestamp;
|
||||
skb_set_timestamp(skb, &eni_vcc->timestamp);
|
||||
DPRINTK("got len %ld\n",length);
|
||||
if (do_rx_dma(vcc,skb,1,length >> 2,length >> 2)) return 1;
|
||||
eni_vcc->rxing++;
|
||||
|
|
|
@ -815,7 +815,7 @@ static void process_incoming (struct fs_dev *dev, struct queue *q)
|
|||
skb_put (skb, qe->p1 & 0xffff);
|
||||
ATM_SKB(skb)->vcc = atm_vcc;
|
||||
atomic_inc(&atm_vcc->stats->rx);
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p (pushed)\n", skb);
|
||||
atm_vcc->push (atm_vcc, skb);
|
||||
fs_dprintk (FS_DEBUG_ALLOC, "Free rec-d: %p\n", pe);
|
||||
|
|
|
@ -1176,7 +1176,7 @@ fore200e_push_rpd(struct fore200e* fore200e, struct atm_vcc* vcc, struct rpd* rp
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
|
||||
#ifdef FORE200E_52BYTE_AAL0_SDU
|
||||
if (cell_header) {
|
||||
|
|
|
@ -1886,7 +1886,7 @@ he_service_rbrq(struct he_dev *he_dev, int group)
|
|||
if (rx_skb_reserve > 0)
|
||||
skb_reserve(skb, rx_skb_reserve);
|
||||
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
|
||||
for (iov = he_vcc->iov_head;
|
||||
iov < he_vcc->iov_tail; ++iov) {
|
||||
|
|
|
@ -1034,7 +1034,7 @@ static void rx_schedule (hrz_dev * dev, int irq) {
|
|||
struct atm_vcc * vcc = ATM_SKB(skb)->vcc;
|
||||
// VC layer stats
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
// end of our responsability
|
||||
vcc->push (vcc, skb);
|
||||
}
|
||||
|
|
|
@ -1101,7 +1101,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
|
|||
cell, ATM_CELL_PAYLOAD);
|
||||
|
||||
ATM_SKB(sb)->vcc = vcc;
|
||||
do_gettimeofday(&sb->stamp);
|
||||
__net_timestamp(sb);
|
||||
vcc->push(vcc, sb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
|
||||
|
@ -1179,7 +1179,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
|
|||
|
||||
skb_trim(skb, len);
|
||||
ATM_SKB(skb)->vcc = vcc;
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
|
||||
vcc->push(vcc, skb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
|
@ -1201,7 +1201,7 @@ dequeue_rx(struct idt77252_dev *card, struct rsq_entry *rsqe)
|
|||
|
||||
skb_trim(skb, len);
|
||||
ATM_SKB(skb)->vcc = vcc;
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
|
||||
vcc->push(vcc, skb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
|
@ -1340,7 +1340,7 @@ idt77252_rx_raw(struct idt77252_dev *card)
|
|||
ATM_CELL_PAYLOAD);
|
||||
|
||||
ATM_SKB(sb)->vcc = vcc;
|
||||
do_gettimeofday(&sb->stamp);
|
||||
__net_timestamp(sb);
|
||||
vcc->push(vcc, sb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
|
||||
|
|
|
@ -1427,7 +1427,7 @@ static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr)
|
|||
skb_put(skb, size);
|
||||
vcc_rx_memcpy(skb->data, lvcc, size);
|
||||
ATM_SKB(skb)->vcc = lvcc->rx.atmvcc;
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
lvcc->rx.atmvcc->push(lvcc->rx.atmvcc, skb);
|
||||
atomic_inc(&lvcc->rx.atmvcc->stats->rx);
|
||||
out:
|
||||
|
|
|
@ -214,8 +214,7 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev);
|
|||
static void __devinit ns_init_card_error(ns_dev *card, int error);
|
||||
static scq_info *get_scq(int size, u32 scd);
|
||||
static void free_scq(scq_info *scq, struct atm_vcc *vcc);
|
||||
static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
|
||||
u32 handle2, u32 addr2);
|
||||
static void push_rxbufs(ns_dev *, struct sk_buff *);
|
||||
static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs);
|
||||
static int ns_open(struct atm_vcc *vcc);
|
||||
static void ns_close(struct atm_vcc *vcc);
|
||||
|
@ -766,6 +765,7 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
|
|||
ns_init_card_error(card, error);
|
||||
return error;
|
||||
}
|
||||
NS_SKB_CB(hb)->buf_type = BUF_NONE;
|
||||
skb_queue_tail(&card->hbpool.queue, hb);
|
||||
card->hbpool.count++;
|
||||
}
|
||||
|
@ -786,9 +786,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
|
|||
ns_init_card_error(card, error);
|
||||
return error;
|
||||
}
|
||||
NS_SKB_CB(lb)->buf_type = BUF_LG;
|
||||
skb_queue_tail(&card->lbpool.queue, lb);
|
||||
skb_reserve(lb, NS_SMBUFSIZE);
|
||||
push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0);
|
||||
push_rxbufs(card, lb);
|
||||
/* Due to the implementation of push_rxbufs() this is 1, not 0 */
|
||||
if (j == 1)
|
||||
{
|
||||
|
@ -822,9 +823,10 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
|
|||
ns_init_card_error(card, error);
|
||||
return error;
|
||||
}
|
||||
NS_SKB_CB(sb)->buf_type = BUF_SM;
|
||||
skb_queue_tail(&card->sbpool.queue, sb);
|
||||
skb_reserve(sb, NS_AAL0_HEADER);
|
||||
push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0);
|
||||
push_rxbufs(card, sb);
|
||||
}
|
||||
/* Test for strange behaviour which leads to crashes */
|
||||
if ((bcount = ns_stat_sfbqc_get(readl(card->membase + STAT))) < card->sbnr.min)
|
||||
|
@ -852,6 +854,7 @@ static int __devinit ns_init_card(int i, struct pci_dev *pcidev)
|
|||
ns_init_card_error(card, error);
|
||||
return error;
|
||||
}
|
||||
NS_SKB_CB(iovb)->buf_type = BUF_NONE;
|
||||
skb_queue_tail(&card->iovpool.queue, iovb);
|
||||
card->iovpool.count++;
|
||||
}
|
||||
|
@ -1078,12 +1081,18 @@ static void free_scq(scq_info *scq, struct atm_vcc *vcc)
|
|||
|
||||
/* The handles passed must be pointers to the sk_buff containing the small
|
||||
or large buffer(s) cast to u32. */
|
||||
static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
|
||||
u32 handle2, u32 addr2)
|
||||
static void push_rxbufs(ns_dev *card, struct sk_buff *skb)
|
||||
{
|
||||
struct ns_skb_cb *cb = NS_SKB_CB(skb);
|
||||
u32 handle1, addr1;
|
||||
u32 handle2, addr2;
|
||||
u32 stat;
|
||||
unsigned long flags;
|
||||
|
||||
/* *BARF* */
|
||||
handle2 = addr2 = 0;
|
||||
handle1 = (u32)skb;
|
||||
addr1 = (u32)virt_to_bus(skb->data);
|
||||
|
||||
#ifdef GENERAL_DEBUG
|
||||
if (!addr1)
|
||||
|
@ -1093,7 +1102,7 @@ static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
|
|||
stat = readl(card->membase + STAT);
|
||||
card->sbfqc = ns_stat_sfbqc_get(stat);
|
||||
card->lbfqc = ns_stat_lfbqc_get(stat);
|
||||
if (type == BUF_SM)
|
||||
if (cb->buf_type == BUF_SM)
|
||||
{
|
||||
if (!addr2)
|
||||
{
|
||||
|
@ -1111,7 +1120,7 @@ static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
|
|||
}
|
||||
}
|
||||
}
|
||||
else /* type == BUF_LG */
|
||||
else /* buf_type == BUF_LG */
|
||||
{
|
||||
if (!addr2)
|
||||
{
|
||||
|
@ -1132,26 +1141,26 @@ static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
|
|||
|
||||
if (addr2)
|
||||
{
|
||||
if (type == BUF_SM)
|
||||
if (cb->buf_type == BUF_SM)
|
||||
{
|
||||
if (card->sbfqc >= card->sbnr.max)
|
||||
{
|
||||
skb_unlink((struct sk_buff *) handle1);
|
||||
skb_unlink((struct sk_buff *) handle1, &card->sbpool.queue);
|
||||
dev_kfree_skb_any((struct sk_buff *) handle1);
|
||||
skb_unlink((struct sk_buff *) handle2);
|
||||
skb_unlink((struct sk_buff *) handle2, &card->sbpool.queue);
|
||||
dev_kfree_skb_any((struct sk_buff *) handle2);
|
||||
return;
|
||||
}
|
||||
else
|
||||
card->sbfqc += 2;
|
||||
}
|
||||
else /* (type == BUF_LG) */
|
||||
else /* (buf_type == BUF_LG) */
|
||||
{
|
||||
if (card->lbfqc >= card->lbnr.max)
|
||||
{
|
||||
skb_unlink((struct sk_buff *) handle1);
|
||||
skb_unlink((struct sk_buff *) handle1, &card->lbpool.queue);
|
||||
dev_kfree_skb_any((struct sk_buff *) handle1);
|
||||
skb_unlink((struct sk_buff *) handle2);
|
||||
skb_unlink((struct sk_buff *) handle2, &card->lbpool.queue);
|
||||
dev_kfree_skb_any((struct sk_buff *) handle2);
|
||||
return;
|
||||
}
|
||||
|
@ -1166,12 +1175,12 @@ static void push_rxbufs(ns_dev *card, u32 type, u32 handle1, u32 addr1,
|
|||
writel(handle2, card->membase + DR2);
|
||||
writel(addr1, card->membase + DR1);
|
||||
writel(handle1, card->membase + DR0);
|
||||
writel(NS_CMD_WRITE_FREEBUFQ | (u32) type, card->membase + CMD);
|
||||
writel(NS_CMD_WRITE_FREEBUFQ | cb->buf_type, card->membase + CMD);
|
||||
|
||||
spin_unlock_irqrestore(&card->res_lock, flags);
|
||||
|
||||
XPRINTK("nicstar%d: Pushing %s buffers at 0x%x and 0x%x.\n", card->index,
|
||||
(type == BUF_SM ? "small" : "large"), addr1, addr2);
|
||||
(cb->buf_type == BUF_SM ? "small" : "large"), addr1, addr2);
|
||||
}
|
||||
|
||||
if (!card->efbie && card->sbfqc >= card->sbnr.min &&
|
||||
|
@ -1322,9 +1331,10 @@ static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
|
|||
card->efbie = 0;
|
||||
break;
|
||||
}
|
||||
NS_SKB_CB(sb)->buf_type = BUF_SM;
|
||||
skb_queue_tail(&card->sbpool.queue, sb);
|
||||
skb_reserve(sb, NS_AAL0_HEADER);
|
||||
push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0);
|
||||
push_rxbufs(card, sb);
|
||||
}
|
||||
card->sbfqc = i;
|
||||
process_rsq(card);
|
||||
|
@ -1348,9 +1358,10 @@ static irqreturn_t ns_irq_handler(int irq, void *dev_id, struct pt_regs *regs)
|
|||
card->efbie = 0;
|
||||
break;
|
||||
}
|
||||
NS_SKB_CB(lb)->buf_type = BUF_LG;
|
||||
skb_queue_tail(&card->lbpool.queue, lb);
|
||||
skb_reserve(lb, NS_SMBUFSIZE);
|
||||
push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0);
|
||||
push_rxbufs(card, lb);
|
||||
}
|
||||
card->lbfqc = i;
|
||||
process_rsq(card);
|
||||
|
@ -2202,7 +2213,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
memcpy(sb->tail, cell, ATM_CELL_PAYLOAD);
|
||||
skb_put(sb, ATM_CELL_PAYLOAD);
|
||||
ATM_SKB(sb)->vcc = vcc;
|
||||
do_gettimeofday(&sb->stamp);
|
||||
__net_timestamp(sb);
|
||||
vcc->push(vcc, sb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
cell += ATM_CELL_PAYLOAD;
|
||||
|
@ -2227,6 +2238,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
recycle_rx_buf(card, skb);
|
||||
return;
|
||||
}
|
||||
NS_SKB_CB(iovb)->buf_type = BUF_NONE;
|
||||
}
|
||||
else
|
||||
if (--card->iovpool.count < card->iovnr.min)
|
||||
|
@ -2234,6 +2246,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
struct sk_buff *new_iovb;
|
||||
if ((new_iovb = alloc_skb(NS_IOVBUFSIZE, GFP_ATOMIC)) != NULL)
|
||||
{
|
||||
NS_SKB_CB(iovb)->buf_type = BUF_NONE;
|
||||
skb_queue_tail(&card->iovpool.queue, new_iovb);
|
||||
card->iovpool.count++;
|
||||
}
|
||||
|
@ -2264,7 +2277,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
|
||||
if (NS_SKB(iovb)->iovcnt == 1)
|
||||
{
|
||||
if (skb->list != &card->sbpool.queue)
|
||||
if (NS_SKB_CB(skb)->buf_type != BUF_SM)
|
||||
{
|
||||
printk("nicstar%d: Expected a small buffer, and this is not one.\n",
|
||||
card->index);
|
||||
|
@ -2278,7 +2291,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
}
|
||||
else /* NS_SKB(iovb)->iovcnt >= 2 */
|
||||
{
|
||||
if (skb->list != &card->lbpool.queue)
|
||||
if (NS_SKB_CB(skb)->buf_type != BUF_LG)
|
||||
{
|
||||
printk("nicstar%d: Expected a large buffer, and this is not one.\n",
|
||||
card->index);
|
||||
|
@ -2322,8 +2335,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
/* skb points to a small buffer */
|
||||
if (!atm_charge(vcc, skb->truesize))
|
||||
{
|
||||
push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data),
|
||||
0, 0);
|
||||
push_rxbufs(card, skb);
|
||||
atomic_inc(&vcc->stats->rx_drop);
|
||||
}
|
||||
else
|
||||
|
@ -2334,7 +2346,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
skb->destructor = ns_sb_destructor;
|
||||
#endif /* NS_USE_DESTRUCTORS */
|
||||
ATM_SKB(skb)->vcc = vcc;
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
vcc->push(vcc, skb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
}
|
||||
|
@ -2350,8 +2362,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
{
|
||||
if (!atm_charge(vcc, sb->truesize))
|
||||
{
|
||||
push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data),
|
||||
0, 0);
|
||||
push_rxbufs(card, sb);
|
||||
atomic_inc(&vcc->stats->rx_drop);
|
||||
}
|
||||
else
|
||||
|
@ -2362,21 +2373,19 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
sb->destructor = ns_sb_destructor;
|
||||
#endif /* NS_USE_DESTRUCTORS */
|
||||
ATM_SKB(sb)->vcc = vcc;
|
||||
do_gettimeofday(&sb->stamp);
|
||||
__net_timestamp(sb);
|
||||
vcc->push(vcc, sb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
}
|
||||
|
||||
push_rxbufs(card, BUF_LG, (u32) skb,
|
||||
(u32) virt_to_bus(skb->data), 0, 0);
|
||||
push_rxbufs(card, skb);
|
||||
|
||||
}
|
||||
else /* len > NS_SMBUFSIZE, the usual case */
|
||||
{
|
||||
if (!atm_charge(vcc, skb->truesize))
|
||||
{
|
||||
push_rxbufs(card, BUF_LG, (u32) skb,
|
||||
(u32) virt_to_bus(skb->data), 0, 0);
|
||||
push_rxbufs(card, skb);
|
||||
atomic_inc(&vcc->stats->rx_drop);
|
||||
}
|
||||
else
|
||||
|
@ -2389,13 +2398,12 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
memcpy(skb->data, sb->data, NS_SMBUFSIZE);
|
||||
skb_put(skb, len - NS_SMBUFSIZE);
|
||||
ATM_SKB(skb)->vcc = vcc;
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
vcc->push(vcc, skb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
}
|
||||
|
||||
push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data),
|
||||
0, 0);
|
||||
push_rxbufs(card, sb);
|
||||
|
||||
}
|
||||
|
||||
|
@ -2430,6 +2438,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
card->hbpool.count++;
|
||||
}
|
||||
}
|
||||
NS_SKB_CB(hb)->buf_type = BUF_NONE;
|
||||
}
|
||||
else
|
||||
if (--card->hbpool.count < card->hbnr.min)
|
||||
|
@ -2437,6 +2446,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
struct sk_buff *new_hb;
|
||||
if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL)
|
||||
{
|
||||
NS_SKB_CB(new_hb)->buf_type = BUF_NONE;
|
||||
skb_queue_tail(&card->hbpool.queue, new_hb);
|
||||
card->hbpool.count++;
|
||||
}
|
||||
|
@ -2444,6 +2454,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
{
|
||||
if ((new_hb = dev_alloc_skb(NS_HBUFSIZE)) != NULL)
|
||||
{
|
||||
NS_SKB_CB(new_hb)->buf_type = BUF_NONE;
|
||||
skb_queue_tail(&card->hbpool.queue, new_hb);
|
||||
card->hbpool.count++;
|
||||
}
|
||||
|
@ -2473,8 +2484,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
remaining = len - iov->iov_len;
|
||||
iov++;
|
||||
/* Free the small buffer */
|
||||
push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data),
|
||||
0, 0);
|
||||
push_rxbufs(card, sb);
|
||||
|
||||
/* Copy all large buffers to the huge buffer and free them */
|
||||
for (j = 1; j < NS_SKB(iovb)->iovcnt; j++)
|
||||
|
@ -2485,8 +2495,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
skb_put(hb, tocopy);
|
||||
iov++;
|
||||
remaining -= tocopy;
|
||||
push_rxbufs(card, BUF_LG, (u32) lb,
|
||||
(u32) virt_to_bus(lb->data), 0, 0);
|
||||
push_rxbufs(card, lb);
|
||||
}
|
||||
#ifdef EXTRA_DEBUG
|
||||
if (remaining != 0 || hb->len != len)
|
||||
|
@ -2496,7 +2505,7 @@ static void dequeue_rx(ns_dev *card, ns_rsqe *rsqe)
|
|||
#ifdef NS_USE_DESTRUCTORS
|
||||
hb->destructor = ns_hb_destructor;
|
||||
#endif /* NS_USE_DESTRUCTORS */
|
||||
do_gettimeofday(&hb->stamp);
|
||||
__net_timestamp(hb);
|
||||
vcc->push(vcc, hb);
|
||||
atomic_inc(&vcc->stats->rx);
|
||||
}
|
||||
|
@ -2527,9 +2536,10 @@ static void ns_sb_destructor(struct sk_buff *sb)
|
|||
sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
|
||||
if (sb == NULL)
|
||||
break;
|
||||
NS_SKB_CB(sb)->buf_type = BUF_SM;
|
||||
skb_queue_tail(&card->sbpool.queue, sb);
|
||||
skb_reserve(sb, NS_AAL0_HEADER);
|
||||
push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0);
|
||||
push_rxbufs(card, sb);
|
||||
} while (card->sbfqc < card->sbnr.min);
|
||||
}
|
||||
|
||||
|
@ -2550,9 +2560,10 @@ static void ns_lb_destructor(struct sk_buff *lb)
|
|||
lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
|
||||
if (lb == NULL)
|
||||
break;
|
||||
NS_SKB_CB(lb)->buf_type = BUF_LG;
|
||||
skb_queue_tail(&card->lbpool.queue, lb);
|
||||
skb_reserve(lb, NS_SMBUFSIZE);
|
||||
push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0);
|
||||
push_rxbufs(card, lb);
|
||||
} while (card->lbfqc < card->lbnr.min);
|
||||
}
|
||||
|
||||
|
@ -2569,6 +2580,7 @@ static void ns_hb_destructor(struct sk_buff *hb)
|
|||
hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
|
||||
if (hb == NULL)
|
||||
break;
|
||||
NS_SKB_CB(hb)->buf_type = BUF_NONE;
|
||||
skb_queue_tail(&card->hbpool.queue, hb);
|
||||
card->hbpool.count++;
|
||||
}
|
||||
|
@ -2577,45 +2589,25 @@ static void ns_hb_destructor(struct sk_buff *hb)
|
|||
#endif /* NS_USE_DESTRUCTORS */
|
||||
|
||||
|
||||
|
||||
static void recycle_rx_buf(ns_dev *card, struct sk_buff *skb)
|
||||
{
|
||||
if (skb->list == &card->sbpool.queue)
|
||||
push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data), 0, 0);
|
||||
else if (skb->list == &card->lbpool.queue)
|
||||
push_rxbufs(card, BUF_LG, (u32) skb, (u32) virt_to_bus(skb->data), 0, 0);
|
||||
else
|
||||
{
|
||||
printk("nicstar%d: What kind of rx buffer is this?\n", card->index);
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
struct ns_skb_cb *cb = NS_SKB_CB(skb);
|
||||
|
||||
if (unlikely(cb->buf_type == BUF_NONE)) {
|
||||
printk("nicstar%d: What kind of rx buffer is this?\n", card->index);
|
||||
dev_kfree_skb_any(skb);
|
||||
} else
|
||||
push_rxbufs(card, skb);
|
||||
}
|
||||
|
||||
|
||||
static void recycle_iovec_rx_bufs(ns_dev *card, struct iovec *iov, int count)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
skb = (struct sk_buff *) (iov++)->iov_base;
|
||||
if (skb->list == &card->sbpool.queue)
|
||||
push_rxbufs(card, BUF_SM, (u32) skb, (u32) virt_to_bus(skb->data),
|
||||
0, 0);
|
||||
else if (skb->list == &card->lbpool.queue)
|
||||
push_rxbufs(card, BUF_LG, (u32) skb, (u32) virt_to_bus(skb->data),
|
||||
0, 0);
|
||||
else
|
||||
{
|
||||
printk("nicstar%d: What kind of rx buffer is this?\n", card->index);
|
||||
dev_kfree_skb_any(skb);
|
||||
}
|
||||
}
|
||||
while (count-- > 0)
|
||||
recycle_rx_buf(card, (struct sk_buff *) (iov++)->iov_base);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb)
|
||||
{
|
||||
if (card->iovpool.count < card->iovnr.max)
|
||||
|
@ -2631,7 +2623,7 @@ static void recycle_iov_buf(ns_dev *card, struct sk_buff *iovb)
|
|||
|
||||
static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
|
||||
{
|
||||
skb_unlink(sb);
|
||||
skb_unlink(sb, &card->sbpool.queue);
|
||||
#ifdef NS_USE_DESTRUCTORS
|
||||
if (card->sbfqc < card->sbnr.min)
|
||||
#else
|
||||
|
@ -2640,10 +2632,10 @@ static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
|
|||
struct sk_buff *new_sb;
|
||||
if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL)
|
||||
{
|
||||
NS_SKB_CB(new_sb)->buf_type = BUF_SM;
|
||||
skb_queue_tail(&card->sbpool.queue, new_sb);
|
||||
skb_reserve(new_sb, NS_AAL0_HEADER);
|
||||
push_rxbufs(card, BUF_SM, (u32) new_sb,
|
||||
(u32) virt_to_bus(new_sb->data), 0, 0);
|
||||
push_rxbufs(card, new_sb);
|
||||
}
|
||||
}
|
||||
if (card->sbfqc < card->sbnr.init)
|
||||
|
@ -2652,10 +2644,10 @@ static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
|
|||
struct sk_buff *new_sb;
|
||||
if ((new_sb = dev_alloc_skb(NS_SMSKBSIZE)) != NULL)
|
||||
{
|
||||
NS_SKB_CB(new_sb)->buf_type = BUF_SM;
|
||||
skb_queue_tail(&card->sbpool.queue, new_sb);
|
||||
skb_reserve(new_sb, NS_AAL0_HEADER);
|
||||
push_rxbufs(card, BUF_SM, (u32) new_sb,
|
||||
(u32) virt_to_bus(new_sb->data), 0, 0);
|
||||
push_rxbufs(card, new_sb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2664,7 +2656,7 @@ static void dequeue_sm_buf(ns_dev *card, struct sk_buff *sb)
|
|||
|
||||
static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb)
|
||||
{
|
||||
skb_unlink(lb);
|
||||
skb_unlink(lb, &card->lbpool.queue);
|
||||
#ifdef NS_USE_DESTRUCTORS
|
||||
if (card->lbfqc < card->lbnr.min)
|
||||
#else
|
||||
|
@ -2673,10 +2665,10 @@ static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb)
|
|||
struct sk_buff *new_lb;
|
||||
if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL)
|
||||
{
|
||||
NS_SKB_CB(new_lb)->buf_type = BUF_LG;
|
||||
skb_queue_tail(&card->lbpool.queue, new_lb);
|
||||
skb_reserve(new_lb, NS_SMBUFSIZE);
|
||||
push_rxbufs(card, BUF_LG, (u32) new_lb,
|
||||
(u32) virt_to_bus(new_lb->data), 0, 0);
|
||||
push_rxbufs(card, new_lb);
|
||||
}
|
||||
}
|
||||
if (card->lbfqc < card->lbnr.init)
|
||||
|
@ -2685,10 +2677,10 @@ static void dequeue_lg_buf(ns_dev *card, struct sk_buff *lb)
|
|||
struct sk_buff *new_lb;
|
||||
if ((new_lb = dev_alloc_skb(NS_LGSKBSIZE)) != NULL)
|
||||
{
|
||||
NS_SKB_CB(new_lb)->buf_type = BUF_LG;
|
||||
skb_queue_tail(&card->lbpool.queue, new_lb);
|
||||
skb_reserve(new_lb, NS_SMBUFSIZE);
|
||||
push_rxbufs(card, BUF_LG, (u32) new_lb,
|
||||
(u32) virt_to_bus(new_lb->data), 0, 0);
|
||||
push_rxbufs(card, new_lb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2880,9 +2872,10 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
|||
sb = __dev_alloc_skb(NS_SMSKBSIZE, GFP_KERNEL);
|
||||
if (sb == NULL)
|
||||
return -ENOMEM;
|
||||
NS_SKB_CB(sb)->buf_type = BUF_SM;
|
||||
skb_queue_tail(&card->sbpool.queue, sb);
|
||||
skb_reserve(sb, NS_AAL0_HEADER);
|
||||
push_rxbufs(card, BUF_SM, (u32) sb, (u32) virt_to_bus(sb->data), 0, 0);
|
||||
push_rxbufs(card, sb);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2894,9 +2887,10 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
|||
lb = __dev_alloc_skb(NS_LGSKBSIZE, GFP_KERNEL);
|
||||
if (lb == NULL)
|
||||
return -ENOMEM;
|
||||
NS_SKB_CB(lb)->buf_type = BUF_LG;
|
||||
skb_queue_tail(&card->lbpool.queue, lb);
|
||||
skb_reserve(lb, NS_SMBUFSIZE);
|
||||
push_rxbufs(card, BUF_LG, (u32) lb, (u32) virt_to_bus(lb->data), 0, 0);
|
||||
push_rxbufs(card, lb);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -2923,6 +2917,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
|||
hb = __dev_alloc_skb(NS_HBUFSIZE, GFP_KERNEL);
|
||||
if (hb == NULL)
|
||||
return -ENOMEM;
|
||||
NS_SKB_CB(hb)->buf_type = BUF_NONE;
|
||||
ns_grab_int_lock(card, flags);
|
||||
skb_queue_tail(&card->hbpool.queue, hb);
|
||||
card->hbpool.count++;
|
||||
|
@ -2953,6 +2948,7 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
|||
iovb = alloc_skb(NS_IOVBUFSIZE, GFP_KERNEL);
|
||||
if (iovb == NULL)
|
||||
return -ENOMEM;
|
||||
NS_SKB_CB(iovb)->buf_type = BUF_NONE;
|
||||
ns_grab_int_lock(card, flags);
|
||||
skb_queue_tail(&card->iovpool.queue, iovb);
|
||||
card->iovpool.count++;
|
||||
|
@ -2979,17 +2975,12 @@ static int ns_ioctl(struct atm_dev *dev, unsigned int cmd, void __user *arg)
|
|||
}
|
||||
|
||||
|
||||
|
||||
static void which_list(ns_dev *card, struct sk_buff *skb)
|
||||
{
|
||||
printk("It's a %s buffer.\n", skb->list == &card->sbpool.queue ?
|
||||
"small" : skb->list == &card->lbpool.queue ? "large" :
|
||||
skb->list == &card->hbpool.queue ? "huge" :
|
||||
skb->list == &card->iovpool.queue ? "iovec" : "unknown");
|
||||
printk("skb buf_type: 0x%08x\n", NS_SKB_CB(skb)->buf_type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void ns_poll(unsigned long arg)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -103,8 +103,14 @@
|
|||
|
||||
#define NS_IOREMAP_SIZE 4096
|
||||
|
||||
#define BUF_SM 0x00000000 /* These two are used for push_rxbufs() */
|
||||
#define BUF_LG 0x00000001 /* CMD, Write_FreeBufQ, LBUF bit */
|
||||
/*
|
||||
* BUF_XX distinguish the Rx buffers depending on their (small/large) size.
|
||||
* BUG_SM and BUG_LG are both used by the driver and the device.
|
||||
* BUF_NONE is only used by the driver.
|
||||
*/
|
||||
#define BUF_SM 0x00000000 /* These two are used for push_rxbufs() */
|
||||
#define BUF_LG 0x00000001 /* CMD, Write_FreeBufQ, LBUF bit */
|
||||
#define BUF_NONE 0xffffffff /* Software only: */
|
||||
|
||||
#define NS_HBUFSIZE 65568 /* Size of max. AAL5 PDU */
|
||||
#define NS_MAX_IOVECS (2 + (65568 - NS_SMBUFSIZE) / \
|
||||
|
@ -684,6 +690,12 @@ enum ns_regs
|
|||
/* Device driver structures ***************************************************/
|
||||
|
||||
|
||||
struct ns_skb_cb {
|
||||
u32 buf_type; /* BUF_SM/BUF_LG/BUF_NONE */
|
||||
};
|
||||
|
||||
#define NS_SKB_CB(skb) ((struct ns_skb_cb *)((skb)->cb))
|
||||
|
||||
typedef struct tsq_info
|
||||
{
|
||||
void *org;
|
||||
|
|
|
@ -400,7 +400,7 @@ unsigned long *x;
|
|||
EVENT("error code 0x%x/0x%x\n",(here[3] & uPD98401_AAL5_ES) >>
|
||||
uPD98401_AAL5_ES_SHIFT,error);
|
||||
skb = ((struct rx_buffer_head *) bus_to_virt(here[2]))->skb;
|
||||
do_gettimeofday(&skb->stamp);
|
||||
__net_timestamp(skb);
|
||||
#if 0
|
||||
printk("[-3..0] 0x%08lx 0x%08lx 0x%08lx 0x%08lx\n",((unsigned *) skb->data)[-3],
|
||||
((unsigned *) skb->data)[-2],((unsigned *) skb->data)[-1],
|
||||
|
@ -417,10 +417,12 @@ printk("dummy: 0x%08lx, 0x%08lx\n",dummy[0],dummy[1]);
|
|||
chan = (here[3] & uPD98401_AAL5_CHAN) >>
|
||||
uPD98401_AAL5_CHAN_SHIFT;
|
||||
if (chan < zatm_dev->chans && zatm_dev->rx_map[chan]) {
|
||||
int pos = ZATM_VCC(vcc)->pool;
|
||||
|
||||
vcc = zatm_dev->rx_map[chan];
|
||||
if (skb == zatm_dev->last_free[ZATM_VCC(vcc)->pool])
|
||||
zatm_dev->last_free[ZATM_VCC(vcc)->pool] = NULL;
|
||||
skb_unlink(skb);
|
||||
if (skb == zatm_dev->last_free[pos])
|
||||
zatm_dev->last_free[pos] = NULL;
|
||||
skb_unlink(skb, zatm_dev->pool + pos);
|
||||
}
|
||||
else {
|
||||
printk(KERN_ERR DEV_LABEL "(itf %d): RX indication "
|
||||
|
|
|
@ -120,7 +120,7 @@ aoenet_xmit(struct sk_buff *sl)
|
|||
* (1) len doesn't include the header by default. I want this.
|
||||
*/
|
||||
static int
|
||||
aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt)
|
||||
aoenet_rcv(struct sk_buff *skb, struct net_device *ifp, struct packet_type *pt, struct net_device *orig_dev)
|
||||
{
|
||||
struct aoe_hdr *h;
|
||||
u32 n;
|
||||
|
|
|
@ -158,7 +158,7 @@ static int bfusb_send_bulk(struct bfusb *bfusb, struct sk_buff *skb)
|
|||
if (err) {
|
||||
BT_ERR("%s bulk tx submit failed urb %p err %d",
|
||||
bfusb->hdev->name, urb, err);
|
||||
skb_unlink(skb);
|
||||
skb_unlink(skb, &bfusb->pending_q);
|
||||
usb_free_urb(urb);
|
||||
} else
|
||||
atomic_inc(&bfusb->pending_tx);
|
||||
|
@ -212,7 +212,7 @@ static void bfusb_tx_complete(struct urb *urb, struct pt_regs *regs)
|
|||
|
||||
read_lock(&bfusb->lock);
|
||||
|
||||
skb_unlink(skb);
|
||||
skb_unlink(skb, &bfusb->pending_q);
|
||||
skb_queue_tail(&bfusb->completed_q, skb);
|
||||
|
||||
bfusb_tx_wakeup(bfusb);
|
||||
|
@ -253,7 +253,7 @@ static int bfusb_rx_submit(struct bfusb *bfusb, struct urb *urb)
|
|||
if (err) {
|
||||
BT_ERR("%s bulk rx submit failed urb %p err %d",
|
||||
bfusb->hdev->name, urb, err);
|
||||
skb_unlink(skb);
|
||||
skb_unlink(skb, &bfusb->pending_q);
|
||||
kfree_skb(skb);
|
||||
usb_free_urb(urb);
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ static inline int bfusb_recv_block(struct bfusb *bfusb, int hdr, unsigned char *
|
|||
}
|
||||
|
||||
skb->dev = (void *) bfusb->hdev;
|
||||
skb->pkt_type = pkt_type;
|
||||
bt_cb(skb)->pkt_type = pkt_type;
|
||||
|
||||
bfusb->reassembly = skb;
|
||||
} else {
|
||||
|
@ -398,7 +398,7 @@ static void bfusb_rx_complete(struct urb *urb, struct pt_regs *regs)
|
|||
buf += len;
|
||||
}
|
||||
|
||||
skb_unlink(skb);
|
||||
skb_unlink(skb, &bfusb->pending_q);
|
||||
kfree_skb(skb);
|
||||
|
||||
bfusb_rx_submit(bfusb, urb);
|
||||
|
@ -485,7 +485,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
|
|||
unsigned char buf[3];
|
||||
int sent = 0, size, count;
|
||||
|
||||
BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
|
||||
BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
|
||||
|
||||
if (!hdev) {
|
||||
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
|
||||
|
@ -497,7 +497,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
|
|||
|
||||
bfusb = (struct bfusb *) hdev->driver_data;
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
hdev->stat.cmd_tx++;
|
||||
break;
|
||||
|
@ -510,7 +510,7 @@ static int bfusb_send_frame(struct sk_buff *skb)
|
|||
};
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
|
||||
count = skb->len;
|
||||
|
||||
|
|
|
@ -270,7 +270,7 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
|
|||
if (!(skb = skb_dequeue(&(info->txq))))
|
||||
break;
|
||||
|
||||
if (skb->pkt_type & 0x80) {
|
||||
if (bt_cb(skb)->pkt_type & 0x80) {
|
||||
/* Disable RTS */
|
||||
info->ctrl_reg |= REG_CONTROL_RTS;
|
||||
outb(info->ctrl_reg, iobase + REG_CONTROL);
|
||||
|
@ -288,13 +288,13 @@ static void bluecard_write_wakeup(bluecard_info_t *info)
|
|||
/* Mark the buffer as dirty */
|
||||
clear_bit(ready_bit, &(info->tx_state));
|
||||
|
||||
if (skb->pkt_type & 0x80) {
|
||||
if (bt_cb(skb)->pkt_type & 0x80) {
|
||||
DECLARE_WAIT_QUEUE_HEAD(wq);
|
||||
DEFINE_WAIT(wait);
|
||||
|
||||
unsigned char baud_reg;
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case PKT_BAUD_RATE_460800:
|
||||
baud_reg = REG_CONTROL_BAUD_RATE_460800;
|
||||
break;
|
||||
|
@ -410,9 +410,9 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
|
|||
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
|
||||
|
||||
info->rx_skb->dev = (void *) info->hdev;
|
||||
info->rx_skb->pkt_type = buf[i];
|
||||
bt_cb(info->rx_skb)->pkt_type = buf[i];
|
||||
|
||||
switch (info->rx_skb->pkt_type) {
|
||||
switch (bt_cb(info->rx_skb)->pkt_type) {
|
||||
|
||||
case 0x00:
|
||||
/* init packet */
|
||||
|
@ -444,7 +444,7 @@ static void bluecard_receive(bluecard_info_t *info, unsigned int offset)
|
|||
|
||||
default:
|
||||
/* unknown packet */
|
||||
BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type);
|
||||
BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
|
||||
info->hdev->stat.err_rx++;
|
||||
|
||||
kfree_skb(info->rx_skb);
|
||||
|
@ -586,21 +586,21 @@ static int bluecard_hci_set_baud_rate(struct hci_dev *hdev, int baud)
|
|||
switch (baud) {
|
||||
case 460800:
|
||||
cmd[4] = 0x00;
|
||||
skb->pkt_type = PKT_BAUD_RATE_460800;
|
||||
bt_cb(skb)->pkt_type = PKT_BAUD_RATE_460800;
|
||||
break;
|
||||
case 230400:
|
||||
cmd[4] = 0x01;
|
||||
skb->pkt_type = PKT_BAUD_RATE_230400;
|
||||
bt_cb(skb)->pkt_type = PKT_BAUD_RATE_230400;
|
||||
break;
|
||||
case 115200:
|
||||
cmd[4] = 0x02;
|
||||
skb->pkt_type = PKT_BAUD_RATE_115200;
|
||||
bt_cb(skb)->pkt_type = PKT_BAUD_RATE_115200;
|
||||
break;
|
||||
case 57600:
|
||||
/* Fall through... */
|
||||
default:
|
||||
cmd[4] = 0x03;
|
||||
skb->pkt_type = PKT_BAUD_RATE_57600;
|
||||
bt_cb(skb)->pkt_type = PKT_BAUD_RATE_57600;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -680,7 +680,7 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
|
|||
|
||||
info = (bluecard_info_t *)(hdev->driver_data);
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
hdev->stat.cmd_tx++;
|
||||
break;
|
||||
|
@ -693,7 +693,7 @@ static int bluecard_hci_send_frame(struct sk_buff *skb)
|
|||
};
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
skb_queue_tail(&(info->txq), skb);
|
||||
|
||||
bluecard_write_wakeup(info);
|
||||
|
|
|
@ -105,7 +105,7 @@ static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int c
|
|||
if (skb) {
|
||||
memcpy(skb_put(skb, len), buf, len);
|
||||
skb->dev = (void *) data->hdev;
|
||||
skb->pkt_type = HCI_ACLDATA_PKT;
|
||||
bt_cb(skb)->pkt_type = HCI_ACLDATA_PKT;
|
||||
hci_recv_frame(skb);
|
||||
}
|
||||
break;
|
||||
|
@ -117,7 +117,7 @@ static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int c
|
|||
if (skb) {
|
||||
memcpy(skb_put(skb, len), buf, len);
|
||||
skb->dev = (void *) data->hdev;
|
||||
skb->pkt_type = HCI_SCODATA_PKT;
|
||||
bt_cb(skb)->pkt_type = HCI_SCODATA_PKT;
|
||||
hci_recv_frame(skb);
|
||||
}
|
||||
break;
|
||||
|
@ -129,7 +129,7 @@ static void bpa10x_recv_bulk(struct bpa10x_data *data, unsigned char *buf, int c
|
|||
if (skb) {
|
||||
memcpy(skb_put(skb, len), buf, len);
|
||||
skb->dev = (void *) data->hdev;
|
||||
skb->pkt_type = HCI_VENDOR_PKT;
|
||||
bt_cb(skb)->pkt_type = HCI_VENDOR_PKT;
|
||||
hci_recv_frame(skb);
|
||||
}
|
||||
break;
|
||||
|
@ -190,7 +190,7 @@ static int bpa10x_recv_event(struct bpa10x_data *data, unsigned char *buf, int s
|
|||
}
|
||||
|
||||
skb->dev = (void *) data->hdev;
|
||||
skb->pkt_type = pkt_type;
|
||||
bt_cb(skb)->pkt_type = pkt_type;
|
||||
|
||||
memcpy(skb_put(skb, size), buf, size);
|
||||
|
||||
|
@ -307,7 +307,8 @@ unlock:
|
|||
read_unlock(&data->lock);
|
||||
}
|
||||
|
||||
static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe, size_t size, int flags, void *data)
|
||||
static inline struct urb *bpa10x_alloc_urb(struct usb_device *udev, unsigned int pipe,
|
||||
size_t size, unsigned int __nocast flags, void *data)
|
||||
{
|
||||
struct urb *urb;
|
||||
struct usb_ctrlrequest *cr;
|
||||
|
@ -487,7 +488,7 @@ static int bpa10x_send_frame(struct sk_buff *skb)
|
|||
struct hci_dev *hdev = (struct hci_dev *) skb->dev;
|
||||
struct bpa10x_data *data;
|
||||
|
||||
BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, skb->pkt_type, skb->len);
|
||||
BT_DBG("hdev %p skb %p type %d len %d", hdev, skb, bt_cb(skb)->pkt_type, skb->len);
|
||||
|
||||
if (!hdev) {
|
||||
BT_ERR("Frame for unknown HCI device");
|
||||
|
@ -500,9 +501,9 @@ static int bpa10x_send_frame(struct sk_buff *skb)
|
|||
data = hdev->driver_data;
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
hdev->stat.cmd_tx++;
|
||||
skb_queue_tail(&data->cmd_queue, skb);
|
||||
|
|
|
@ -259,11 +259,11 @@ static void bt3c_receive(bt3c_info_t *info)
|
|||
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
|
||||
|
||||
info->rx_skb->dev = (void *) info->hdev;
|
||||
info->rx_skb->pkt_type = inb(iobase + DATA_L);
|
||||
bt_cb(info->rx_skb)->pkt_type = inb(iobase + DATA_L);
|
||||
inb(iobase + DATA_H);
|
||||
//printk("bt3c: PACKET_TYPE=%02x\n", info->rx_skb->pkt_type);
|
||||
//printk("bt3c: PACKET_TYPE=%02x\n", bt_cb(info->rx_skb)->pkt_type);
|
||||
|
||||
switch (info->rx_skb->pkt_type) {
|
||||
switch (bt_cb(info->rx_skb)->pkt_type) {
|
||||
|
||||
case HCI_EVENT_PKT:
|
||||
info->rx_state = RECV_WAIT_EVENT_HEADER;
|
||||
|
@ -282,7 +282,7 @@ static void bt3c_receive(bt3c_info_t *info)
|
|||
|
||||
default:
|
||||
/* Unknown packet */
|
||||
BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type);
|
||||
BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
|
||||
info->hdev->stat.err_rx++;
|
||||
clear_bit(HCI_RUNNING, &(info->hdev->flags));
|
||||
|
||||
|
@ -439,7 +439,7 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
|
|||
|
||||
info = (bt3c_info_t *) (hdev->driver_data);
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
hdev->stat.cmd_tx++;
|
||||
break;
|
||||
|
@ -452,7 +452,7 @@ static int bt3c_hci_send_frame(struct sk_buff *skb)
|
|||
};
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
skb_queue_tail(&(info->txq), skb);
|
||||
|
||||
spin_lock_irqsave(&(info->lock), flags);
|
||||
|
|
|
@ -211,9 +211,9 @@ static void btuart_receive(btuart_info_t *info)
|
|||
if (info->rx_state == RECV_WAIT_PACKET_TYPE) {
|
||||
|
||||
info->rx_skb->dev = (void *) info->hdev;
|
||||
info->rx_skb->pkt_type = inb(iobase + UART_RX);
|
||||
bt_cb(info->rx_skb)->pkt_type = inb(iobase + UART_RX);
|
||||
|
||||
switch (info->rx_skb->pkt_type) {
|
||||
switch (bt_cb(info->rx_skb)->pkt_type) {
|
||||
|
||||
case HCI_EVENT_PKT:
|
||||
info->rx_state = RECV_WAIT_EVENT_HEADER;
|
||||
|
@ -232,7 +232,7 @@ static void btuart_receive(btuart_info_t *info)
|
|||
|
||||
default:
|
||||
/* Unknown packet */
|
||||
BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type);
|
||||
BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
|
||||
info->hdev->stat.err_rx++;
|
||||
clear_bit(HCI_RUNNING, &(info->hdev->flags));
|
||||
|
||||
|
@ -447,7 +447,7 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
|
|||
|
||||
info = (btuart_info_t *)(hdev->driver_data);
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
hdev->stat.cmd_tx++;
|
||||
break;
|
||||
|
@ -460,7 +460,7 @@ static int btuart_hci_send_frame(struct sk_buff *skb)
|
|||
};
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
memcpy(skb_push(skb, 1), &(skb->pkt_type), 1);
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
skb_queue_tail(&(info->txq), skb);
|
||||
|
||||
btuart_write_wakeup(info);
|
||||
|
|
|
@ -251,7 +251,7 @@ static void dtl1_receive(dtl1_info_t *info)
|
|||
info->rx_count = nsh->len + (nsh->len & 0x0001);
|
||||
break;
|
||||
case RECV_WAIT_DATA:
|
||||
info->rx_skb->pkt_type = nsh->type;
|
||||
bt_cb(info->rx_skb)->pkt_type = nsh->type;
|
||||
|
||||
/* remove PAD byte if it exists */
|
||||
if (nsh->len & 0x0001) {
|
||||
|
@ -262,7 +262,7 @@ static void dtl1_receive(dtl1_info_t *info)
|
|||
/* remove NSH */
|
||||
skb_pull(info->rx_skb, NSHL);
|
||||
|
||||
switch (info->rx_skb->pkt_type) {
|
||||
switch (bt_cb(info->rx_skb)->pkt_type) {
|
||||
case 0x80:
|
||||
/* control data for the Nokia Card */
|
||||
dtl1_control(info, info->rx_skb);
|
||||
|
@ -272,12 +272,12 @@ static void dtl1_receive(dtl1_info_t *info)
|
|||
case 0x84:
|
||||
/* send frame to the HCI layer */
|
||||
info->rx_skb->dev = (void *) info->hdev;
|
||||
info->rx_skb->pkt_type &= 0x0f;
|
||||
bt_cb(info->rx_skb)->pkt_type &= 0x0f;
|
||||
hci_recv_frame(info->rx_skb);
|
||||
break;
|
||||
default:
|
||||
/* unknown packet */
|
||||
BT_ERR("Unknown HCI packet with type 0x%02x received", info->rx_skb->pkt_type);
|
||||
BT_ERR("Unknown HCI packet with type 0x%02x received", bt_cb(info->rx_skb)->pkt_type);
|
||||
kfree_skb(info->rx_skb);
|
||||
break;
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ static int dtl1_hci_send_frame(struct sk_buff *skb)
|
|||
|
||||
info = (dtl1_info_t *)(hdev->driver_data);
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
hdev->stat.cmd_tx++;
|
||||
nsh.type = 0x81;
|
||||
|
|
|
@ -149,7 +149,7 @@ static int bcsp_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
|||
return 0;
|
||||
}
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_ACLDATA_PKT:
|
||||
case HCI_COMMAND_PKT:
|
||||
skb_queue_tail(&bcsp->rel, skb);
|
||||
|
@ -227,7 +227,7 @@ static struct sk_buff *bcsp_prepare_pkt(struct bcsp_struct *bcsp, u8 *data,
|
|||
if (!nskb)
|
||||
return NULL;
|
||||
|
||||
nskb->pkt_type = pkt_type;
|
||||
bt_cb(nskb)->pkt_type = pkt_type;
|
||||
|
||||
bcsp_slip_msgdelim(nskb);
|
||||
|
||||
|
@ -286,7 +286,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
|
|||
since they have priority */
|
||||
|
||||
if ((skb = skb_dequeue(&bcsp->unrel)) != NULL) {
|
||||
struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
|
||||
struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
|
||||
if (nskb) {
|
||||
kfree_skb(skb);
|
||||
return nskb;
|
||||
|
@ -303,7 +303,7 @@ static struct sk_buff *bcsp_dequeue(struct hci_uart *hu)
|
|||
spin_lock_irqsave(&bcsp->unack.lock, flags);
|
||||
|
||||
if (bcsp->unack.qlen < BCSP_TXWINSIZE && (skb = skb_dequeue(&bcsp->rel)) != NULL) {
|
||||
struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, skb->pkt_type);
|
||||
struct sk_buff *nskb = bcsp_prepare_pkt(bcsp, skb->data, skb->len, bt_cb(skb)->pkt_type);
|
||||
if (nskb) {
|
||||
__skb_queue_tail(&bcsp->unack, skb);
|
||||
mod_timer(&bcsp->tbcsp, jiffies + HZ / 4);
|
||||
|
@ -401,7 +401,7 @@ static void bcsp_handle_le_pkt(struct hci_uart *hu)
|
|||
if (!nskb)
|
||||
return;
|
||||
memcpy(skb_put(nskb, 4), conf_rsp_pkt, 4);
|
||||
nskb->pkt_type = BCSP_LE_PKT;
|
||||
bt_cb(nskb)->pkt_type = BCSP_LE_PKT;
|
||||
|
||||
skb_queue_head(&bcsp->unrel, nskb);
|
||||
hci_uart_tx_wakeup(hu);
|
||||
|
@ -483,14 +483,14 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
|
|||
bcsp_pkt_cull(bcsp);
|
||||
if ((bcsp->rx_skb->data[1] & 0x0f) == 6 &&
|
||||
bcsp->rx_skb->data[0] & 0x80) {
|
||||
bcsp->rx_skb->pkt_type = HCI_ACLDATA_PKT;
|
||||
bt_cb(bcsp->rx_skb)->pkt_type = HCI_ACLDATA_PKT;
|
||||
pass_up = 1;
|
||||
} else if ((bcsp->rx_skb->data[1] & 0x0f) == 5 &&
|
||||
bcsp->rx_skb->data[0] & 0x80) {
|
||||
bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
|
||||
bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
|
||||
pass_up = 1;
|
||||
} else if ((bcsp->rx_skb->data[1] & 0x0f) == 7) {
|
||||
bcsp->rx_skb->pkt_type = HCI_SCODATA_PKT;
|
||||
bt_cb(bcsp->rx_skb)->pkt_type = HCI_SCODATA_PKT;
|
||||
pass_up = 1;
|
||||
} else if ((bcsp->rx_skb->data[1] & 0x0f) == 1 &&
|
||||
!(bcsp->rx_skb->data[0] & 0x80)) {
|
||||
|
@ -512,7 +512,7 @@ static inline void bcsp_complete_rx_pkt(struct hci_uart *hu)
|
|||
hdr.evt = 0xff;
|
||||
hdr.plen = bcsp->rx_skb->len;
|
||||
memcpy(skb_push(bcsp->rx_skb, HCI_EVENT_HDR_SIZE), &hdr, HCI_EVENT_HDR_SIZE);
|
||||
bcsp->rx_skb->pkt_type = HCI_EVENT_PKT;
|
||||
bt_cb(bcsp->rx_skb)->pkt_type = HCI_EVENT_PKT;
|
||||
|
||||
hci_recv_frame(bcsp->rx_skb);
|
||||
} else {
|
||||
|
|
|
@ -112,7 +112,7 @@ static int h4_enqueue(struct hci_uart *hu, struct sk_buff *skb)
|
|||
BT_DBG("hu %p skb %p", hu, skb);
|
||||
|
||||
/* Prepend skb with frame type */
|
||||
memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
skb_queue_tail(&h4->txq, skb);
|
||||
return 0;
|
||||
}
|
||||
|
@ -239,7 +239,7 @@ static int h4_recv(struct hci_uart *hu, void *data, int count)
|
|||
return 0;
|
||||
}
|
||||
h4->rx_skb->dev = (void *) hu->hdev;
|
||||
h4->rx_skb->pkt_type = type;
|
||||
bt_cb(h4->rx_skb)->pkt_type = type;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -153,7 +153,7 @@ restart:
|
|||
break;
|
||||
}
|
||||
|
||||
hci_uart_tx_complete(hu, skb->pkt_type);
|
||||
hci_uart_tx_complete(hu, bt_cb(skb)->pkt_type);
|
||||
kfree_skb(skb);
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ static int hci_uart_send_frame(struct sk_buff *skb)
|
|||
hu = (struct hci_uart *) hdev->driver_data;
|
||||
tty = hu->tty;
|
||||
|
||||
BT_DBG("%s: type %d len %d", hdev->name, skb->pkt_type, skb->len);
|
||||
BT_DBG("%s: type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
|
||||
|
||||
hu->proto->enqueue(hu, skb);
|
||||
|
||||
|
|
|
@ -127,7 +127,7 @@ static struct usb_device_id blacklist_ids[] = {
|
|||
{ } /* Terminating entry */
|
||||
};
|
||||
|
||||
static struct _urb *_urb_alloc(int isoc, int gfp)
|
||||
static struct _urb *_urb_alloc(int isoc, unsigned int __nocast gfp)
|
||||
{
|
||||
struct _urb *_urb = kmalloc(sizeof(struct _urb) +
|
||||
sizeof(struct usb_iso_packet_descriptor) * isoc, gfp);
|
||||
|
@ -443,7 +443,7 @@ static int __tx_submit(struct hci_usb *husb, struct _urb *_urb)
|
|||
|
||||
static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
|
||||
{
|
||||
struct _urb *_urb = __get_completed(husb, skb->pkt_type);
|
||||
struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
|
||||
struct usb_ctrlrequest *dr;
|
||||
struct urb *urb;
|
||||
|
||||
|
@ -451,7 +451,7 @@ static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
|
|||
_urb = _urb_alloc(0, GFP_ATOMIC);
|
||||
if (!_urb)
|
||||
return -ENOMEM;
|
||||
_urb->type = skb->pkt_type;
|
||||
_urb->type = bt_cb(skb)->pkt_type;
|
||||
|
||||
dr = kmalloc(sizeof(*dr), GFP_ATOMIC);
|
||||
if (!dr) {
|
||||
|
@ -479,7 +479,7 @@ static inline int hci_usb_send_ctrl(struct hci_usb *husb, struct sk_buff *skb)
|
|||
|
||||
static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
|
||||
{
|
||||
struct _urb *_urb = __get_completed(husb, skb->pkt_type);
|
||||
struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
|
||||
struct urb *urb;
|
||||
int pipe;
|
||||
|
||||
|
@ -487,7 +487,7 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
|
|||
_urb = _urb_alloc(0, GFP_ATOMIC);
|
||||
if (!_urb)
|
||||
return -ENOMEM;
|
||||
_urb->type = skb->pkt_type;
|
||||
_urb->type = bt_cb(skb)->pkt_type;
|
||||
}
|
||||
|
||||
urb = &_urb->urb;
|
||||
|
@ -505,14 +505,14 @@ static inline int hci_usb_send_bulk(struct hci_usb *husb, struct sk_buff *skb)
|
|||
#ifdef CONFIG_BT_HCIUSB_SCO
|
||||
static inline int hci_usb_send_isoc(struct hci_usb *husb, struct sk_buff *skb)
|
||||
{
|
||||
struct _urb *_urb = __get_completed(husb, skb->pkt_type);
|
||||
struct _urb *_urb = __get_completed(husb, bt_cb(skb)->pkt_type);
|
||||
struct urb *urb;
|
||||
|
||||
if (!_urb) {
|
||||
_urb = _urb_alloc(HCI_MAX_ISOC_FRAMES, GFP_ATOMIC);
|
||||
if (!_urb)
|
||||
return -ENOMEM;
|
||||
_urb->type = skb->pkt_type;
|
||||
_urb->type = bt_cb(skb)->pkt_type;
|
||||
}
|
||||
|
||||
BT_DBG("%s skb %p len %d", husb->hdev->name, skb, skb->len);
|
||||
|
@ -601,11 +601,11 @@ static int hci_usb_send_frame(struct sk_buff *skb)
|
|||
if (!test_bit(HCI_RUNNING, &hdev->flags))
|
||||
return -EBUSY;
|
||||
|
||||
BT_DBG("%s type %d len %d", hdev->name, skb->pkt_type, skb->len);
|
||||
BT_DBG("%s type %d len %d", hdev->name, bt_cb(skb)->pkt_type, skb->len);
|
||||
|
||||
husb = (struct hci_usb *) hdev->driver_data;
|
||||
|
||||
switch (skb->pkt_type) {
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
hdev->stat.cmd_tx++;
|
||||
break;
|
||||
|
@ -627,7 +627,7 @@ static int hci_usb_send_frame(struct sk_buff *skb)
|
|||
|
||||
read_lock(&husb->completion_lock);
|
||||
|
||||
skb_queue_tail(__transmit_q(husb, skb->pkt_type), skb);
|
||||
skb_queue_tail(__transmit_q(husb, bt_cb(skb)->pkt_type), skb);
|
||||
hci_usb_tx_wakeup(husb);
|
||||
|
||||
read_unlock(&husb->completion_lock);
|
||||
|
@ -682,7 +682,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
|
|||
return -ENOMEM;
|
||||
}
|
||||
skb->dev = (void *) husb->hdev;
|
||||
skb->pkt_type = type;
|
||||
bt_cb(skb)->pkt_type = type;
|
||||
|
||||
__reassembly(husb, type) = skb;
|
||||
|
||||
|
@ -702,6 +702,7 @@ static inline int __recv_frame(struct hci_usb *husb, int type, void *data, int c
|
|||
if (!scb->expect) {
|
||||
/* Complete frame */
|
||||
__reassembly(husb, type) = NULL;
|
||||
bt_cb(skb)->pkt_type = type;
|
||||
hci_recv_frame(skb);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,229 +1,220 @@
|
|||
/*
|
||||
BlueZ - Bluetooth protocol stack for Linux
|
||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
|
||||
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation;
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
SOFTWARE IS DISCLAIMED.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Bluetooth HCI virtual device driver.
|
||||
*
|
||||
* $Id: hci_vhci.c,v 1.3 2002/04/17 17:37:20 maxk Exp $
|
||||
* Bluetooth virtual HCI driver
|
||||
*
|
||||
* Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
* Copyright (C) 2002-2003 Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
* Copyright (C) 2004-2005 Marcel Holtmann <marcel@holtmann.org>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
*/
|
||||
#define VERSION "1.1"
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/poll.h>
|
||||
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/miscdevice.h>
|
||||
|
||||
#include <asm/system.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <net/bluetooth/bluetooth.h>
|
||||
#include <net/bluetooth/hci_core.h>
|
||||
#include "hci_vhci.h"
|
||||
|
||||
/* HCI device part */
|
||||
#ifndef CONFIG_BT_HCIVHCI_DEBUG
|
||||
#undef BT_DBG
|
||||
#define BT_DBG(D...)
|
||||
#endif
|
||||
|
||||
static int hci_vhci_open(struct hci_dev *hdev)
|
||||
#define VERSION "1.2"
|
||||
|
||||
static int minor = MISC_DYNAMIC_MINOR;
|
||||
|
||||
struct vhci_data {
|
||||
struct hci_dev *hdev;
|
||||
|
||||
unsigned long flags;
|
||||
|
||||
wait_queue_head_t read_wait;
|
||||
struct sk_buff_head readq;
|
||||
|
||||
struct fasync_struct *fasync;
|
||||
};
|
||||
|
||||
#define VHCI_FASYNC 0x0010
|
||||
|
||||
static struct miscdevice vhci_miscdev;
|
||||
|
||||
static int vhci_open_dev(struct hci_dev *hdev)
|
||||
{
|
||||
set_bit(HCI_RUNNING, &hdev->flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hci_vhci_flush(struct hci_dev *hdev)
|
||||
static int vhci_close_dev(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
|
||||
skb_queue_purge(&hci_vhci->readq);
|
||||
return 0;
|
||||
}
|
||||
struct vhci_data *vhci = hdev->driver_data;
|
||||
|
||||
static int hci_vhci_close(struct hci_dev *hdev)
|
||||
{
|
||||
if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags))
|
||||
return 0;
|
||||
|
||||
hci_vhci_flush(hdev);
|
||||
skb_queue_purge(&vhci->readq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hci_vhci_destruct(struct hci_dev *hdev)
|
||||
static int vhci_flush(struct hci_dev *hdev)
|
||||
{
|
||||
struct hci_vhci_struct *vhci;
|
||||
struct vhci_data *vhci = hdev->driver_data;
|
||||
|
||||
if (!hdev) return;
|
||||
skb_queue_purge(&vhci->readq);
|
||||
|
||||
vhci = (struct hci_vhci_struct *) hdev->driver_data;
|
||||
kfree(vhci);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hci_vhci_send_frame(struct sk_buff *skb)
|
||||
static int vhci_send_frame(struct sk_buff *skb)
|
||||
{
|
||||
struct hci_dev* hdev = (struct hci_dev *) skb->dev;
|
||||
struct hci_vhci_struct *hci_vhci;
|
||||
struct vhci_data *vhci;
|
||||
|
||||
if (!hdev) {
|
||||
BT_ERR("Frame for uknown device (hdev=NULL)");
|
||||
BT_ERR("Frame for unknown HCI device (hdev=NULL)");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!test_bit(HCI_RUNNING, &hdev->flags))
|
||||
return -EBUSY;
|
||||
|
||||
hci_vhci = (struct hci_vhci_struct *) hdev->driver_data;
|
||||
vhci = hdev->driver_data;
|
||||
|
||||
memcpy(skb_push(skb, 1), &skb->pkt_type, 1);
|
||||
skb_queue_tail(&hci_vhci->readq, skb);
|
||||
memcpy(skb_push(skb, 1), &bt_cb(skb)->pkt_type, 1);
|
||||
skb_queue_tail(&vhci->readq, skb);
|
||||
|
||||
if (hci_vhci->flags & VHCI_FASYNC)
|
||||
kill_fasync(&hci_vhci->fasync, SIGIO, POLL_IN);
|
||||
wake_up_interruptible(&hci_vhci->read_wait);
|
||||
if (vhci->flags & VHCI_FASYNC)
|
||||
kill_fasync(&vhci->fasync, SIGIO, POLL_IN);
|
||||
|
||||
wake_up_interruptible(&vhci->read_wait);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Character device part */
|
||||
|
||||
/* Poll */
|
||||
static unsigned int hci_vhci_chr_poll(struct file *file, poll_table * wait)
|
||||
{
|
||||
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
|
||||
|
||||
poll_wait(file, &hci_vhci->read_wait, wait);
|
||||
|
||||
if (!skb_queue_empty(&hci_vhci->readq))
|
||||
return POLLIN | POLLRDNORM;
|
||||
|
||||
return POLLOUT | POLLWRNORM;
|
||||
static void vhci_destruct(struct hci_dev *hdev)
|
||||
{
|
||||
kfree(hdev->driver_data);
|
||||
}
|
||||
|
||||
/* Get packet from user space buffer(already verified) */
|
||||
static inline ssize_t hci_vhci_get_user(struct hci_vhci_struct *hci_vhci, const char __user *buf, size_t count)
|
||||
static inline ssize_t vhci_get_user(struct vhci_data *vhci,
|
||||
const char __user *buf, size_t count)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
|
||||
if (count > HCI_MAX_FRAME_SIZE)
|
||||
return -EINVAL;
|
||||
|
||||
if (!(skb = bt_skb_alloc(count, GFP_KERNEL)))
|
||||
skb = bt_skb_alloc(count, GFP_KERNEL);
|
||||
if (!skb)
|
||||
return -ENOMEM;
|
||||
|
||||
|
||||
if (copy_from_user(skb_put(skb, count), buf, count)) {
|
||||
kfree_skb(skb);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
skb->dev = (void *) hci_vhci->hdev;
|
||||
skb->pkt_type = *((__u8 *) skb->data);
|
||||
skb->dev = (void *) vhci->hdev;
|
||||
bt_cb(skb)->pkt_type = *((__u8 *) skb->data);
|
||||
skb_pull(skb, 1);
|
||||
|
||||
hci_recv_frame(skb);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Write */
|
||||
static ssize_t hci_vhci_chr_write(struct file * file, const char __user * buf,
|
||||
size_t count, loff_t *pos)
|
||||
{
|
||||
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
|
||||
|
||||
if (!access_ok(VERIFY_READ, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
return hci_vhci_get_user(hci_vhci, buf, count);
|
||||
}
|
||||
|
||||
/* Put packet to user space buffer(already verified) */
|
||||
static inline ssize_t hci_vhci_put_user(struct hci_vhci_struct *hci_vhci,
|
||||
struct sk_buff *skb, char __user *buf,
|
||||
int count)
|
||||
static inline ssize_t vhci_put_user(struct vhci_data *vhci,
|
||||
struct sk_buff *skb, char __user *buf, int count)
|
||||
{
|
||||
int len = count, total = 0;
|
||||
char __user *ptr = buf;
|
||||
int len, total = 0;
|
||||
|
||||
len = min_t(unsigned int, skb->len, count);
|
||||
|
||||
len = min_t(unsigned int, skb->len, len);
|
||||
if (copy_to_user(ptr, skb->data, len))
|
||||
return -EFAULT;
|
||||
|
||||
total += len;
|
||||
|
||||
hci_vhci->hdev->stat.byte_tx += len;
|
||||
switch (skb->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
hci_vhci->hdev->stat.cmd_tx++;
|
||||
break;
|
||||
vhci->hdev->stat.byte_tx += len;
|
||||
|
||||
case HCI_ACLDATA_PKT:
|
||||
hci_vhci->hdev->stat.acl_tx++;
|
||||
break;
|
||||
switch (bt_cb(skb)->pkt_type) {
|
||||
case HCI_COMMAND_PKT:
|
||||
vhci->hdev->stat.cmd_tx++;
|
||||
break;
|
||||
|
||||
case HCI_SCODATA_PKT:
|
||||
hci_vhci->hdev->stat.cmd_tx++;
|
||||
break;
|
||||
case HCI_ACLDATA_PKT:
|
||||
vhci->hdev->stat.acl_tx++;
|
||||
break;
|
||||
|
||||
case HCI_SCODATA_PKT:
|
||||
vhci->hdev->stat.cmd_tx++;
|
||||
break;
|
||||
};
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
/* Read */
|
||||
static ssize_t hci_vhci_chr_read(struct file * file, char __user * buf, size_t count, loff_t *pos)
|
||||
static loff_t vhci_llseek(struct file * file, loff_t offset, int origin)
|
||||
{
|
||||
return -ESPIPE;
|
||||
}
|
||||
|
||||
static ssize_t vhci_read(struct file * file, char __user * buf, size_t count, loff_t *pos)
|
||||
{
|
||||
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
|
||||
DECLARE_WAITQUEUE(wait, current);
|
||||
struct vhci_data *vhci = file->private_data;
|
||||
struct sk_buff *skb;
|
||||
ssize_t ret = 0;
|
||||
|
||||
add_wait_queue(&hci_vhci->read_wait, &wait);
|
||||
add_wait_queue(&vhci->read_wait, &wait);
|
||||
while (count) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
|
||||
/* Read frames from device queue */
|
||||
if (!(skb = skb_dequeue(&hci_vhci->readq))) {
|
||||
skb = skb_dequeue(&vhci->readq);
|
||||
if (!skb) {
|
||||
if (file->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
break;
|
||||
}
|
||||
|
||||
if (signal_pending(current)) {
|
||||
ret = -ERESTARTSYS;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Nothing to read, let's sleep */
|
||||
schedule();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (access_ok(VERIFY_WRITE, buf, count))
|
||||
ret = hci_vhci_put_user(hci_vhci, skb, buf, count);
|
||||
ret = vhci_put_user(vhci, skb, buf, count);
|
||||
else
|
||||
ret = -EFAULT;
|
||||
|
||||
|
@ -231,84 +222,90 @@ static ssize_t hci_vhci_chr_read(struct file * file, char __user * buf, size_t c
|
|||
break;
|
||||
}
|
||||
set_current_state(TASK_RUNNING);
|
||||
remove_wait_queue(&hci_vhci->read_wait, &wait);
|
||||
remove_wait_queue(&vhci->read_wait, &wait);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static loff_t hci_vhci_chr_lseek(struct file * file, loff_t offset, int origin)
|
||||
static ssize_t vhci_write(struct file *file,
|
||||
const char __user *buf, size_t count, loff_t *pos)
|
||||
{
|
||||
return -ESPIPE;
|
||||
struct vhci_data *vhci = file->private_data;
|
||||
|
||||
if (!access_ok(VERIFY_READ, buf, count))
|
||||
return -EFAULT;
|
||||
|
||||
return vhci_get_user(vhci, buf, count);
|
||||
}
|
||||
|
||||
static int hci_vhci_chr_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
|
||||
static unsigned int vhci_poll(struct file *file, poll_table *wait)
|
||||
{
|
||||
struct vhci_data *vhci = file->private_data;
|
||||
|
||||
poll_wait(file, &vhci->read_wait, wait);
|
||||
|
||||
if (!skb_queue_empty(&vhci->readq))
|
||||
return POLLIN | POLLRDNORM;
|
||||
|
||||
return POLLOUT | POLLWRNORM;
|
||||
}
|
||||
|
||||
static int vhci_ioctl(struct inode *inode, struct file *file,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int hci_vhci_chr_fasync(int fd, struct file *file, int on)
|
||||
static int vhci_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
|
||||
int ret;
|
||||
|
||||
if ((ret = fasync_helper(fd, file, on, &hci_vhci->fasync)) < 0)
|
||||
return ret;
|
||||
|
||||
if (on)
|
||||
hci_vhci->flags |= VHCI_FASYNC;
|
||||
else
|
||||
hci_vhci->flags &= ~VHCI_FASYNC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hci_vhci_chr_open(struct inode *inode, struct file * file)
|
||||
{
|
||||
struct hci_vhci_struct *hci_vhci = NULL;
|
||||
struct vhci_data *vhci;
|
||||
struct hci_dev *hdev;
|
||||
|
||||
if (!(hci_vhci = kmalloc(sizeof(struct hci_vhci_struct), GFP_KERNEL)))
|
||||
vhci = kmalloc(sizeof(struct vhci_data), GFP_KERNEL);
|
||||
if (!vhci)
|
||||
return -ENOMEM;
|
||||
|
||||
memset(hci_vhci, 0, sizeof(struct hci_vhci_struct));
|
||||
memset(vhci, 0, sizeof(struct vhci_data));
|
||||
|
||||
skb_queue_head_init(&hci_vhci->readq);
|
||||
init_waitqueue_head(&hci_vhci->read_wait);
|
||||
skb_queue_head_init(&vhci->readq);
|
||||
init_waitqueue_head(&vhci->read_wait);
|
||||
|
||||
/* Initialize and register HCI device */
|
||||
hdev = hci_alloc_dev();
|
||||
if (!hdev) {
|
||||
kfree(hci_vhci);
|
||||
kfree(vhci);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
hci_vhci->hdev = hdev;
|
||||
vhci->hdev = hdev;
|
||||
|
||||
hdev->type = HCI_VHCI;
|
||||
hdev->driver_data = hci_vhci;
|
||||
hdev->driver_data = vhci;
|
||||
SET_HCIDEV_DEV(hdev, vhci_miscdev.dev);
|
||||
|
||||
hdev->open = hci_vhci_open;
|
||||
hdev->close = hci_vhci_close;
|
||||
hdev->flush = hci_vhci_flush;
|
||||
hdev->send = hci_vhci_send_frame;
|
||||
hdev->destruct = hci_vhci_destruct;
|
||||
hdev->open = vhci_open_dev;
|
||||
hdev->close = vhci_close_dev;
|
||||
hdev->flush = vhci_flush;
|
||||
hdev->send = vhci_send_frame;
|
||||
hdev->destruct = vhci_destruct;
|
||||
|
||||
hdev->owner = THIS_MODULE;
|
||||
|
||||
|
||||
if (hci_register_dev(hdev) < 0) {
|
||||
kfree(hci_vhci);
|
||||
BT_ERR("Can't register HCI device");
|
||||
kfree(vhci);
|
||||
hci_free_dev(hdev);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
file->private_data = hci_vhci;
|
||||
return nonseekable_open(inode, file);
|
||||
file->private_data = vhci;
|
||||
|
||||
return nonseekable_open(inode, file);
|
||||
}
|
||||
|
||||
static int hci_vhci_chr_close(struct inode *inode, struct file *file)
|
||||
static int vhci_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
struct hci_vhci_struct *hci_vhci = (struct hci_vhci_struct *) file->private_data;
|
||||
struct hci_dev *hdev = hci_vhci->hdev;
|
||||
struct vhci_data *vhci = file->private_data;
|
||||
struct hci_dev *hdev = vhci->hdev;
|
||||
|
||||
if (hci_unregister_dev(hdev) < 0) {
|
||||
BT_ERR("Can't unregister HCI device %s", hdev->name);
|
||||
|
@ -317,48 +314,71 @@ static int hci_vhci_chr_close(struct inode *inode, struct file *file)
|
|||
hci_free_dev(hdev);
|
||||
|
||||
file->private_data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations hci_vhci_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = hci_vhci_chr_lseek,
|
||||
.read = hci_vhci_chr_read,
|
||||
.write = hci_vhci_chr_write,
|
||||
.poll = hci_vhci_chr_poll,
|
||||
.ioctl = hci_vhci_chr_ioctl,
|
||||
.open = hci_vhci_chr_open,
|
||||
.release = hci_vhci_chr_close,
|
||||
.fasync = hci_vhci_chr_fasync
|
||||
static int vhci_fasync(int fd, struct file *file, int on)
|
||||
{
|
||||
struct vhci_data *vhci = file->private_data;
|
||||
int err;
|
||||
|
||||
err = fasync_helper(fd, file, on, &vhci->fasync);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (on)
|
||||
vhci->flags |= VHCI_FASYNC;
|
||||
else
|
||||
vhci->flags &= ~VHCI_FASYNC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct file_operations vhci_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = vhci_llseek,
|
||||
.read = vhci_read,
|
||||
.write = vhci_write,
|
||||
.poll = vhci_poll,
|
||||
.ioctl = vhci_ioctl,
|
||||
.open = vhci_open,
|
||||
.release = vhci_release,
|
||||
.fasync = vhci_fasync,
|
||||
};
|
||||
|
||||
static struct miscdevice hci_vhci_miscdev=
|
||||
{
|
||||
VHCI_MINOR,
|
||||
"hci_vhci",
|
||||
&hci_vhci_fops
|
||||
static struct miscdevice vhci_miscdev= {
|
||||
.name = "vhci",
|
||||
.fops = &vhci_fops,
|
||||
};
|
||||
|
||||
static int __init hci_vhci_init(void)
|
||||
static int __init vhci_init(void)
|
||||
{
|
||||
BT_INFO("VHCI driver ver %s", VERSION);
|
||||
BT_INFO("Virtual HCI driver ver %s", VERSION);
|
||||
|
||||
if (misc_register(&hci_vhci_miscdev)) {
|
||||
BT_ERR("Can't register misc device %d\n", VHCI_MINOR);
|
||||
vhci_miscdev.minor = minor;
|
||||
|
||||
if (misc_register(&vhci_miscdev) < 0) {
|
||||
BT_ERR("Can't register misc device with minor %d", minor);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hci_vhci_cleanup(void)
|
||||
static void __exit vhci_exit(void)
|
||||
{
|
||||
misc_deregister(&hci_vhci_miscdev);
|
||||
if (misc_deregister(&vhci_miscdev) < 0)
|
||||
BT_ERR("Can't unregister misc device with minor %d", minor);
|
||||
}
|
||||
|
||||
module_init(hci_vhci_init);
|
||||
module_exit(hci_vhci_cleanup);
|
||||
module_init(vhci_init);
|
||||
module_exit(vhci_exit);
|
||||
|
||||
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>");
|
||||
MODULE_DESCRIPTION("Bluetooth VHCI driver ver " VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
module_param(minor, int, 0444);
|
||||
MODULE_PARM_DESC(minor, "Miscellaneous minor device number");
|
||||
|
||||
MODULE_AUTHOR("Maxim Krasnyansky <maxk@qualcomm.com>, Marcel Holtmann <marcel@holtmann.org>");
|
||||
MODULE_DESCRIPTION("Bluetooth virtual HCI driver ver " VERSION);
|
||||
MODULE_VERSION(VERSION);
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
BlueZ - Bluetooth protocol stack for Linux
|
||||
Copyright (C) 2000-2001 Qualcomm Incorporated
|
||||
|
||||
Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License version 2 as
|
||||
published by the Free Software Foundation;
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
||||
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
|
||||
IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
|
||||
CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
|
||||
COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
|
||||
SOFTWARE IS DISCLAIMED.
|
||||
*/
|
||||
|
||||
/*
|
||||
* $Id: hci_vhci.h,v 1.1.1.1 2002/03/08 21:03:15 maxk Exp $
|
||||
*/
|
||||
|
||||
#ifndef __HCI_VHCI_H
|
||||
#define __HCI_VHCI_H
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct hci_vhci_struct {
|
||||
struct hci_dev *hdev;
|
||||
__u32 flags;
|
||||
wait_queue_head_t read_wait;
|
||||
struct sk_buff_head readq;
|
||||
struct fasync_struct *fasync;
|
||||
};
|
||||
|
||||
/* VHCI device flags */
|
||||
#define VHCI_FASYNC 0x0010
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#define VHCI_DEV "/dev/vhci"
|
||||
#define VHCI_MINOR 250
|
||||
|
||||
#endif /* __HCI_VHCI_H */
|
|
@ -1589,6 +1589,40 @@ u32 secure_tcpv6_port_ephemeral(const __u32 *saddr, const __u32 *daddr, __u16 dp
|
|||
EXPORT_SYMBOL(secure_tcpv6_port_ephemeral);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
|
||||
/* Similar to secure_tcp_sequence_number but generate a 48 bit value
|
||||
* bit's 32-47 increase every key exchange
|
||||
* 0-31 hash(source, dest)
|
||||
*/
|
||||
u64 secure_dccp_sequence_number(__u32 saddr, __u32 daddr,
|
||||
__u16 sport, __u16 dport)
|
||||
{
|
||||
struct timeval tv;
|
||||
u64 seq;
|
||||
__u32 hash[4];
|
||||
struct keydata *keyptr = get_keyptr();
|
||||
|
||||
hash[0] = saddr;
|
||||
hash[1] = daddr;
|
||||
hash[2] = (sport << 16) + dport;
|
||||
hash[3] = keyptr->secret[11];
|
||||
|
||||
seq = half_md4_transform(hash, keyptr->secret);
|
||||
seq |= ((u64)keyptr->count) << (32 - HASH_BITS);
|
||||
|
||||
do_gettimeofday(&tv);
|
||||
seq += tv.tv_usec + tv.tv_sec * 1000000;
|
||||
seq &= (1ull << 48) - 1;
|
||||
#if 0
|
||||
printk("dccp init_seq(%lx, %lx, %d, %d) = %d\n",
|
||||
saddr, daddr, sport, dport, seq);
|
||||
#endif
|
||||
return seq;
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(secure_dccp_sequence_number);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_INET */
|
||||
|
||||
|
||||
|
|
|
@ -681,7 +681,7 @@ static void handle_packet_response(struct hpsb_host *host, int tcode,
|
|||
return;
|
||||
}
|
||||
|
||||
__skb_unlink(skb, skb->list);
|
||||
__skb_unlink(skb, &host->pending_packet_queue);
|
||||
|
||||
if (packet->state == hpsb_queued) {
|
||||
packet->sendtime = jiffies;
|
||||
|
@ -989,7 +989,7 @@ void abort_timedouts(unsigned long __opaque)
|
|||
packet = (struct hpsb_packet *)skb->data;
|
||||
|
||||
if (time_before(packet->sendtime + expire, jiffies)) {
|
||||
__skb_unlink(skb, skb->list);
|
||||
__skb_unlink(skb, &host->pending_packet_queue);
|
||||
packet->state = hpsb_complete;
|
||||
packet->ack_code = ACKX_TIMEOUT;
|
||||
queue_packet_complete(packet);
|
||||
|
|
|
@ -606,7 +606,7 @@ handle_ack(act2000_card *card, act2000_chan *chan, __u8 blocknr) {
|
|||
if ((((m->msg.data_b3_req.fakencci >> 8) & 0xff) == chan->ncci) &&
|
||||
(m->msg.data_b3_req.blocknr == blocknr)) {
|
||||
/* found corresponding DATA_B3_REQ */
|
||||
skb_unlink(tmp);
|
||||
skb_unlink(tmp, &card->ackq);
|
||||
chan->queued -= m->msg.data_b3_req.datalen;
|
||||
if (m->msg.data_b3_req.flags)
|
||||
ret = m->msg.data_b3_req.datalen;
|
||||
|
|
|
@ -1786,7 +1786,6 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
|
|||
lp->stats.rx_bytes += skb->len;
|
||||
}
|
||||
skb->dev = ndev;
|
||||
skb->input_dev = ndev;
|
||||
skb->pkt_type = PACKET_HOST;
|
||||
skb->mac.raw = skb->data;
|
||||
#ifdef ISDN_DEBUG_NET_DUMP
|
||||
|
|
|
@ -1177,7 +1177,6 @@ isdn_ppp_push_higher(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff
|
|||
mlp->huptimer = 0;
|
||||
#endif /* CONFIG_IPPP_FILTER */
|
||||
skb->dev = dev;
|
||||
skb->input_dev = dev;
|
||||
skb->mac.raw = skb->data;
|
||||
netif_rx(skb);
|
||||
/* net_dev->local->stats.rx_packets++; done in isdn_net.c */
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
|
||||
#define DRV_MODULE_NAME "bnx2"
|
||||
#define PFX DRV_MODULE_NAME ": "
|
||||
#define DRV_MODULE_VERSION "1.2.19"
|
||||
#define DRV_MODULE_RELDATE "May 23, 2005"
|
||||
#define DRV_MODULE_VERSION "1.2.20"
|
||||
#define DRV_MODULE_RELDATE "August 22, 2005"
|
||||
|
||||
#define RUN_AT(x) (jiffies + (x))
|
||||
|
||||
|
@ -52,7 +52,6 @@ static struct {
|
|||
{ "HP NC370i Multifunction Gigabit Server Adapter" },
|
||||
{ "Broadcom NetXtreme II BCM5706 1000Base-SX" },
|
||||
{ "HP NC370F Multifunction Gigabit Server Adapter" },
|
||||
{ 0 },
|
||||
};
|
||||
|
||||
static struct pci_device_id bnx2_pci_tbl[] = {
|
||||
|
@ -108,6 +107,15 @@ static struct flash_spec flash_table[] =
|
|||
|
||||
MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
|
||||
|
||||
static inline u32 bnx2_tx_avail(struct bnx2 *bp)
|
||||
{
|
||||
u32 diff = TX_RING_IDX(bp->tx_prod) - TX_RING_IDX(bp->tx_cons);
|
||||
|
||||
if (diff > MAX_TX_DESC_CNT)
|
||||
diff = (diff & MAX_TX_DESC_CNT) - 1;
|
||||
return (bp->tx_ring_size - diff);
|
||||
}
|
||||
|
||||
static u32
|
||||
bnx2_reg_rd_ind(struct bnx2 *bp, u32 offset)
|
||||
{
|
||||
|
@ -807,7 +815,19 @@ bnx2_setup_serdes_phy(struct bnx2 *bp)
|
|||
bnx2_write_phy(bp, MII_ADVERTISE, new_adv);
|
||||
bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART |
|
||||
BMCR_ANENABLE);
|
||||
bp->serdes_an_pending = SERDES_AN_TIMEOUT / bp->timer_interval;
|
||||
if (CHIP_NUM(bp) == CHIP_NUM_5706) {
|
||||
/* Speed up link-up time when the link partner
|
||||
* does not autonegotiate which is very common
|
||||
* in blade servers. Some blade servers use
|
||||
* IPMI for kerboard input and it's important
|
||||
* to minimize link disruptions. Autoneg. involves
|
||||
* exchanging base pages plus 3 next pages and
|
||||
* normally completes in about 120 msec.
|
||||
*/
|
||||
bp->current_interval = SERDES_AN_TIMEOUT;
|
||||
bp->serdes_an_pending = 1;
|
||||
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -1327,22 +1347,17 @@ bnx2_tx_int(struct bnx2 *bp)
|
|||
}
|
||||
}
|
||||
|
||||
atomic_add(tx_free_bd, &bp->tx_avail_bd);
|
||||
bp->tx_cons = sw_cons;
|
||||
|
||||
if (unlikely(netif_queue_stopped(bp->dev))) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bp->tx_lock, flags);
|
||||
spin_lock(&bp->tx_lock);
|
||||
if ((netif_queue_stopped(bp->dev)) &&
|
||||
(atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)) {
|
||||
(bnx2_tx_avail(bp) > MAX_SKB_FRAGS)) {
|
||||
|
||||
netif_wake_queue(bp->dev);
|
||||
}
|
||||
spin_unlock_irqrestore(&bp->tx_lock, flags);
|
||||
spin_unlock(&bp->tx_lock);
|
||||
}
|
||||
|
||||
bp->tx_cons = sw_cons;
|
||||
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
@ -1523,15 +1538,12 @@ bnx2_msi(int irq, void *dev_instance, struct pt_regs *regs)
|
|||
BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
|
||||
|
||||
/* Return here if interrupt is disabled. */
|
||||
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
|
||||
return IRQ_RETVAL(1);
|
||||
}
|
||||
if (unlikely(atomic_read(&bp->intr_sem) != 0))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
if (netif_rx_schedule_prep(dev)) {
|
||||
__netif_rx_schedule(dev);
|
||||
}
|
||||
netif_rx_schedule(dev);
|
||||
|
||||
return IRQ_RETVAL(1);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t
|
||||
|
@ -1549,22 +1561,19 @@ bnx2_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
|
|||
if ((bp->status_blk->status_idx == bp->last_status_idx) ||
|
||||
(REG_RD(bp, BNX2_PCICFG_MISC_STATUS) &
|
||||
BNX2_PCICFG_MISC_STATUS_INTA_VALUE))
|
||||
return IRQ_RETVAL(0);
|
||||
return IRQ_NONE;
|
||||
|
||||
REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
|
||||
BNX2_PCICFG_INT_ACK_CMD_USE_INT_HC_PARAM |
|
||||
BNX2_PCICFG_INT_ACK_CMD_MASK_INT);
|
||||
|
||||
/* Return here if interrupt is shared and is disabled. */
|
||||
if (unlikely(atomic_read(&bp->intr_sem) != 0)) {
|
||||
return IRQ_RETVAL(1);
|
||||
}
|
||||
if (unlikely(atomic_read(&bp->intr_sem) != 0))
|
||||
return IRQ_HANDLED;
|
||||
|
||||
if (netif_rx_schedule_prep(dev)) {
|
||||
__netif_rx_schedule(dev);
|
||||
}
|
||||
netif_rx_schedule(dev);
|
||||
|
||||
return IRQ_RETVAL(1);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1581,11 +1590,9 @@ bnx2_poll(struct net_device *dev, int *budget)
|
|||
(bp->status_blk->status_attn_bits_ack &
|
||||
STATUS_ATTN_BITS_LINK_STATE)) {
|
||||
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bp->phy_lock, flags);
|
||||
spin_lock(&bp->phy_lock);
|
||||
bnx2_phy_int(bp);
|
||||
spin_unlock_irqrestore(&bp->phy_lock, flags);
|
||||
spin_unlock(&bp->phy_lock);
|
||||
}
|
||||
|
||||
if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) {
|
||||
|
@ -1628,9 +1635,8 @@ bnx2_set_rx_mode(struct net_device *dev)
|
|||
struct bnx2 *bp = dev->priv;
|
||||
u32 rx_mode, sort_mode;
|
||||
int i;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bp->phy_lock, flags);
|
||||
spin_lock_bh(&bp->phy_lock);
|
||||
|
||||
rx_mode = bp->rx_mode & ~(BNX2_EMAC_RX_MODE_PROMISCUOUS |
|
||||
BNX2_EMAC_RX_MODE_KEEP_VLAN_TAG);
|
||||
|
@ -1691,7 +1697,7 @@ bnx2_set_rx_mode(struct net_device *dev)
|
|||
REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode);
|
||||
REG_WR(bp, BNX2_RPM_SORT_USER0, sort_mode | BNX2_RPM_SORT_USER0_ENA);
|
||||
|
||||
spin_unlock_irqrestore(&bp->phy_lock, flags);
|
||||
spin_unlock_bh(&bp->phy_lock);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -2960,7 +2966,6 @@ bnx2_init_tx_ring(struct bnx2 *bp)
|
|||
bp->tx_prod = 0;
|
||||
bp->tx_cons = 0;
|
||||
bp->tx_prod_bseq = 0;
|
||||
atomic_set(&bp->tx_avail_bd, bp->tx_ring_size);
|
||||
|
||||
val = BNX2_L2CTX_TYPE_TYPE_L2;
|
||||
val |= BNX2_L2CTX_TYPE_SIZE_L2;
|
||||
|
@ -3507,11 +3512,11 @@ bnx2_test_registers(struct bnx2 *bp)
|
|||
rw_mask = reg_tbl[i].rw_mask;
|
||||
ro_mask = reg_tbl[i].ro_mask;
|
||||
|
||||
save_val = readl((u8 *) bp->regview + offset);
|
||||
save_val = readl(bp->regview + offset);
|
||||
|
||||
writel(0, (u8 *) bp->regview + offset);
|
||||
writel(0, bp->regview + offset);
|
||||
|
||||
val = readl((u8 *) bp->regview + offset);
|
||||
val = readl(bp->regview + offset);
|
||||
if ((val & rw_mask) != 0) {
|
||||
goto reg_test_err;
|
||||
}
|
||||
|
@ -3520,9 +3525,9 @@ bnx2_test_registers(struct bnx2 *bp)
|
|||
goto reg_test_err;
|
||||
}
|
||||
|
||||
writel(0xffffffff, (u8 *) bp->regview + offset);
|
||||
writel(0xffffffff, bp->regview + offset);
|
||||
|
||||
val = readl((u8 *) bp->regview + offset);
|
||||
val = readl(bp->regview + offset);
|
||||
if ((val & rw_mask) != rw_mask) {
|
||||
goto reg_test_err;
|
||||
}
|
||||
|
@ -3531,11 +3536,11 @@ bnx2_test_registers(struct bnx2 *bp)
|
|||
goto reg_test_err;
|
||||
}
|
||||
|
||||
writel(save_val, (u8 *) bp->regview + offset);
|
||||
writel(save_val, bp->regview + offset);
|
||||
continue;
|
||||
|
||||
reg_test_err:
|
||||
writel(save_val, (u8 *) bp->regview + offset);
|
||||
writel(save_val, bp->regview + offset);
|
||||
ret = -ENODEV;
|
||||
break;
|
||||
}
|
||||
|
@ -3752,10 +3757,10 @@ bnx2_test_link(struct bnx2 *bp)
|
|||
{
|
||||
u32 bmsr;
|
||||
|
||||
spin_lock_irq(&bp->phy_lock);
|
||||
spin_lock_bh(&bp->phy_lock);
|
||||
bnx2_read_phy(bp, MII_BMSR, &bmsr);
|
||||
bnx2_read_phy(bp, MII_BMSR, &bmsr);
|
||||
spin_unlock_irq(&bp->phy_lock);
|
||||
spin_unlock_bh(&bp->phy_lock);
|
||||
|
||||
if (bmsr & BMSR_LSTATUS) {
|
||||
return 0;
|
||||
|
@ -3801,6 +3806,9 @@ bnx2_timer(unsigned long data)
|
|||
struct bnx2 *bp = (struct bnx2 *) data;
|
||||
u32 msg;
|
||||
|
||||
if (!netif_running(bp->dev))
|
||||
return;
|
||||
|
||||
if (atomic_read(&bp->intr_sem) != 0)
|
||||
goto bnx2_restart_timer;
|
||||
|
||||
|
@ -3809,15 +3817,16 @@ bnx2_timer(unsigned long data)
|
|||
|
||||
if ((bp->phy_flags & PHY_SERDES_FLAG) &&
|
||||
(CHIP_NUM(bp) == CHIP_NUM_5706)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bp->phy_lock, flags);
|
||||
spin_lock(&bp->phy_lock);
|
||||
if (bp->serdes_an_pending) {
|
||||
bp->serdes_an_pending--;
|
||||
}
|
||||
else if ((bp->link_up == 0) && (bp->autoneg & AUTONEG_SPEED)) {
|
||||
u32 bmcr;
|
||||
|
||||
bp->current_interval = bp->timer_interval;
|
||||
|
||||
bnx2_read_phy(bp, MII_BMCR, &bmcr);
|
||||
|
||||
if (bmcr & BMCR_ANENABLE) {
|
||||
|
@ -3860,14 +3869,14 @@ bnx2_timer(unsigned long data)
|
|||
|
||||
}
|
||||
}
|
||||
else
|
||||
bp->current_interval = bp->timer_interval;
|
||||
|
||||
spin_unlock_irqrestore(&bp->phy_lock, flags);
|
||||
spin_unlock(&bp->phy_lock);
|
||||
}
|
||||
|
||||
bnx2_restart_timer:
|
||||
bp->timer.expires = RUN_AT(bp->timer_interval);
|
||||
|
||||
add_timer(&bp->timer);
|
||||
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
||||
}
|
||||
|
||||
/* Called with rtnl_lock */
|
||||
|
@ -3920,12 +3929,7 @@ bnx2_open(struct net_device *dev)
|
|||
return rc;
|
||||
}
|
||||
|
||||
init_timer(&bp->timer);
|
||||
|
||||
bp->timer.expires = RUN_AT(bp->timer_interval);
|
||||
bp->timer.data = (unsigned long) bp;
|
||||
bp->timer.function = bnx2_timer;
|
||||
add_timer(&bp->timer);
|
||||
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
||||
|
||||
atomic_set(&bp->intr_sem, 0);
|
||||
|
||||
|
@ -3976,12 +3980,17 @@ bnx2_reset_task(void *data)
|
|||
{
|
||||
struct bnx2 *bp = data;
|
||||
|
||||
if (!netif_running(bp->dev))
|
||||
return;
|
||||
|
||||
bp->in_reset_task = 1;
|
||||
bnx2_netif_stop(bp);
|
||||
|
||||
bnx2_init_nic(bp);
|
||||
|
||||
atomic_set(&bp->intr_sem, 1);
|
||||
bnx2_netif_start(bp);
|
||||
bp->in_reset_task = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -4041,9 +4050,7 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
u16 prod, ring_prod;
|
||||
int i;
|
||||
|
||||
if (unlikely(atomic_read(&bp->tx_avail_bd) <
|
||||
(skb_shinfo(skb)->nr_frags + 1))) {
|
||||
|
||||
if (unlikely(bnx2_tx_avail(bp) < (skb_shinfo(skb)->nr_frags + 1))) {
|
||||
netif_stop_queue(dev);
|
||||
printk(KERN_ERR PFX "%s: BUG! Tx ring full when queue awake!\n",
|
||||
dev->name);
|
||||
|
@ -4140,8 +4147,6 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
prod = NEXT_TX_BD(prod);
|
||||
bp->tx_prod_bseq += skb->len;
|
||||
|
||||
atomic_sub(last_frag + 1, &bp->tx_avail_bd);
|
||||
|
||||
REG_WR16(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BIDX, prod);
|
||||
REG_WR(bp, MB_TX_CID_ADDR + BNX2_L2CTX_TX_HOST_BSEQ, bp->tx_prod_bseq);
|
||||
|
||||
|
@ -4150,17 +4155,13 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
bp->tx_prod = prod;
|
||||
dev->trans_start = jiffies;
|
||||
|
||||
if (unlikely(atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS)) {
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&bp->tx_lock, flags);
|
||||
if (atomic_read(&bp->tx_avail_bd) <= MAX_SKB_FRAGS) {
|
||||
netif_stop_queue(dev);
|
||||
|
||||
if (atomic_read(&bp->tx_avail_bd) > MAX_SKB_FRAGS)
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
spin_unlock_irqrestore(&bp->tx_lock, flags);
|
||||
if (unlikely(bnx2_tx_avail(bp) <= MAX_SKB_FRAGS)) {
|
||||
spin_lock(&bp->tx_lock);
|
||||
netif_stop_queue(dev);
|
||||
|
||||
if (bnx2_tx_avail(bp) > MAX_SKB_FRAGS)
|
||||
netif_wake_queue(dev);
|
||||
spin_unlock(&bp->tx_lock);
|
||||
}
|
||||
|
||||
return NETDEV_TX_OK;
|
||||
|
@ -4173,7 +4174,13 @@ bnx2_close(struct net_device *dev)
|
|||
struct bnx2 *bp = dev->priv;
|
||||
u32 reset_code;
|
||||
|
||||
flush_scheduled_work();
|
||||
/* Calling flush_scheduled_work() may deadlock because
|
||||
* linkwatch_event() may be on the workqueue and it will try to get
|
||||
* the rtnl_lock which we are holding.
|
||||
*/
|
||||
while (bp->in_reset_task)
|
||||
msleep(1);
|
||||
|
||||
bnx2_netif_stop(bp);
|
||||
del_timer_sync(&bp->timer);
|
||||
if (bp->wol)
|
||||
|
@ -4390,11 +4397,11 @@ bnx2_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
|
|||
bp->req_line_speed = req_line_speed;
|
||||
bp->req_duplex = req_duplex;
|
||||
|
||||
spin_lock_irq(&bp->phy_lock);
|
||||
spin_lock_bh(&bp->phy_lock);
|
||||
|
||||
bnx2_setup_phy(bp);
|
||||
|
||||
spin_unlock_irq(&bp->phy_lock);
|
||||
spin_unlock_bh(&bp->phy_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -4464,19 +4471,20 @@ bnx2_nway_reset(struct net_device *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
spin_lock_irq(&bp->phy_lock);
|
||||
spin_lock_bh(&bp->phy_lock);
|
||||
|
||||
/* Force a link down visible on the other side */
|
||||
if (bp->phy_flags & PHY_SERDES_FLAG) {
|
||||
bnx2_write_phy(bp, MII_BMCR, BMCR_LOOPBACK);
|
||||
spin_unlock_irq(&bp->phy_lock);
|
||||
spin_unlock_bh(&bp->phy_lock);
|
||||
|
||||
msleep(20);
|
||||
|
||||
spin_lock_irq(&bp->phy_lock);
|
||||
spin_lock_bh(&bp->phy_lock);
|
||||
if (CHIP_NUM(bp) == CHIP_NUM_5706) {
|
||||
bp->serdes_an_pending = SERDES_AN_TIMEOUT /
|
||||
bp->timer_interval;
|
||||
bp->current_interval = SERDES_AN_TIMEOUT;
|
||||
bp->serdes_an_pending = 1;
|
||||
mod_timer(&bp->timer, jiffies + bp->current_interval);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4484,7 +4492,7 @@ bnx2_nway_reset(struct net_device *dev)
|
|||
bmcr &= ~BMCR_LOOPBACK;
|
||||
bnx2_write_phy(bp, MII_BMCR, bmcr | BMCR_ANRESTART | BMCR_ANENABLE);
|
||||
|
||||
spin_unlock_irq(&bp->phy_lock);
|
||||
spin_unlock_bh(&bp->phy_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -4670,11 +4678,11 @@ bnx2_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause)
|
|||
bp->autoneg &= ~AUTONEG_FLOW_CTRL;
|
||||
}
|
||||
|
||||
spin_lock_irq(&bp->phy_lock);
|
||||
spin_lock_bh(&bp->phy_lock);
|
||||
|
||||
bnx2_setup_phy(bp);
|
||||
|
||||
spin_unlock_irq(&bp->phy_lock);
|
||||
spin_unlock_bh(&bp->phy_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -4698,7 +4706,7 @@ bnx2_set_rx_csum(struct net_device *dev, u32 data)
|
|||
|
||||
#define BNX2_NUM_STATS 45
|
||||
|
||||
struct {
|
||||
static struct {
|
||||
char string[ETH_GSTRING_LEN];
|
||||
} bnx2_stats_str_arr[BNX2_NUM_STATS] = {
|
||||
{ "rx_bytes" },
|
||||
|
@ -4750,7 +4758,7 @@ struct {
|
|||
|
||||
#define STATS_OFFSET32(offset_name) (offsetof(struct statistics_block, offset_name) / 4)
|
||||
|
||||
unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
|
||||
static unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
|
||||
STATS_OFFSET32(stat_IfHCInOctets_hi),
|
||||
STATS_OFFSET32(stat_IfHCInBadOctets_hi),
|
||||
STATS_OFFSET32(stat_IfHCOutOctets_hi),
|
||||
|
@ -4801,7 +4809,7 @@ unsigned long bnx2_stats_offset_arr[BNX2_NUM_STATS] = {
|
|||
/* stat_IfHCInBadOctets and stat_Dot3StatsCarrierSenseErrors are
|
||||
* skipped because of errata.
|
||||
*/
|
||||
u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
|
||||
static u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
|
||||
8,0,8,8,8,8,8,8,8,8,
|
||||
4,0,4,4,4,4,4,4,4,4,
|
||||
4,4,4,4,4,4,4,4,4,4,
|
||||
|
@ -4811,7 +4819,7 @@ u8 bnx2_5706_stats_len_arr[BNX2_NUM_STATS] = {
|
|||
|
||||
#define BNX2_NUM_TESTS 6
|
||||
|
||||
struct {
|
||||
static struct {
|
||||
char string[ETH_GSTRING_LEN];
|
||||
} bnx2_tests_str_arr[BNX2_NUM_TESTS] = {
|
||||
{ "register_test (offline)" },
|
||||
|
@ -4910,7 +4918,7 @@ bnx2_get_ethtool_stats(struct net_device *dev,
|
|||
struct bnx2 *bp = dev->priv;
|
||||
int i;
|
||||
u32 *hw_stats = (u32 *) bp->stats_blk;
|
||||
u8 *stats_len_arr = 0;
|
||||
u8 *stats_len_arr = NULL;
|
||||
|
||||
if (hw_stats == NULL) {
|
||||
memset(buf, 0, sizeof(u64) * BNX2_NUM_STATS);
|
||||
|
@ -5012,7 +5020,7 @@ static struct ethtool_ops bnx2_ethtool_ops = {
|
|||
static int
|
||||
bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
||||
{
|
||||
struct mii_ioctl_data *data = (struct mii_ioctl_data *)&ifr->ifr_data;
|
||||
struct mii_ioctl_data *data = if_mii(ifr);
|
||||
struct bnx2 *bp = dev->priv;
|
||||
int err;
|
||||
|
||||
|
@ -5024,9 +5032,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
case SIOCGMIIREG: {
|
||||
u32 mii_regval;
|
||||
|
||||
spin_lock_irq(&bp->phy_lock);
|
||||
spin_lock_bh(&bp->phy_lock);
|
||||
err = bnx2_read_phy(bp, data->reg_num & 0x1f, &mii_regval);
|
||||
spin_unlock_irq(&bp->phy_lock);
|
||||
spin_unlock_bh(&bp->phy_lock);
|
||||
|
||||
data->val_out = mii_regval;
|
||||
|
||||
|
@ -5037,9 +5045,9 @@ bnx2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
|
|||
if (!capable(CAP_NET_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
spin_lock_irq(&bp->phy_lock);
|
||||
spin_lock_bh(&bp->phy_lock);
|
||||
err = bnx2_write_phy(bp, data->reg_num & 0x1f, data->val_in);
|
||||
spin_unlock_irq(&bp->phy_lock);
|
||||
spin_unlock_bh(&bp->phy_lock);
|
||||
|
||||
return err;
|
||||
|
||||
|
@ -5057,6 +5065,9 @@ bnx2_change_mac_addr(struct net_device *dev, void *p)
|
|||
struct sockaddr *addr = p;
|
||||
struct bnx2 *bp = dev->priv;
|
||||
|
||||
if (!is_valid_ether_addr(addr->sa_data))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
|
||||
if (netif_running(dev))
|
||||
bnx2_set_mac_addr(bp);
|
||||
|
@ -5305,6 +5316,7 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
|
|||
bp->stats_ticks = 1000000 & 0xffff00;
|
||||
|
||||
bp->timer_interval = HZ;
|
||||
bp->current_interval = HZ;
|
||||
|
||||
/* Disable WOL support if we are running on a SERDES chip. */
|
||||
if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
|
||||
|
@ -5328,6 +5340,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
|
|||
bp->req_line_speed = 0;
|
||||
if (bp->phy_flags & PHY_SERDES_FLAG) {
|
||||
bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
|
||||
|
||||
reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
|
||||
BNX2_PORT_HW_CFG_CONFIG);
|
||||
reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
|
||||
if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
|
||||
bp->autoneg = 0;
|
||||
bp->req_line_speed = bp->line_speed = SPEED_1000;
|
||||
bp->req_duplex = DUPLEX_FULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
bp->advertising = ETHTOOL_ALL_COPPER_SPEED | ADVERTISED_Autoneg;
|
||||
|
@ -5335,11 +5356,17 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev)
|
|||
|
||||
bp->req_flow_ctrl = FLOW_CTRL_RX | FLOW_CTRL_TX;
|
||||
|
||||
init_timer(&bp->timer);
|
||||
bp->timer.expires = RUN_AT(bp->timer_interval);
|
||||
bp->timer.data = (unsigned long) bp;
|
||||
bp->timer.function = bnx2_timer;
|
||||
|
||||
return 0;
|
||||
|
||||
err_out_unmap:
|
||||
if (bp->regview) {
|
||||
iounmap(bp->regview);
|
||||
bp->regview = NULL;
|
||||
}
|
||||
|
||||
err_out_release:
|
||||
|
@ -5454,6 +5481,8 @@ bnx2_remove_one(struct pci_dev *pdev)
|
|||
struct net_device *dev = pci_get_drvdata(pdev);
|
||||
struct bnx2 *bp = dev->priv;
|
||||
|
||||
flush_scheduled_work();
|
||||
|
||||
unregister_netdev(dev);
|
||||
|
||||
if (bp->regview)
|
||||
|
@ -5505,12 +5534,12 @@ bnx2_resume(struct pci_dev *pdev)
|
|||
}
|
||||
|
||||
static struct pci_driver bnx2_pci_driver = {
|
||||
name: DRV_MODULE_NAME,
|
||||
id_table: bnx2_pci_tbl,
|
||||
probe: bnx2_init_one,
|
||||
remove: __devexit_p(bnx2_remove_one),
|
||||
suspend: bnx2_suspend,
|
||||
resume: bnx2_resume,
|
||||
.name = DRV_MODULE_NAME,
|
||||
.id_table = bnx2_pci_tbl,
|
||||
.probe = bnx2_init_one,
|
||||
.remove = __devexit_p(bnx2_remove_one),
|
||||
.suspend = bnx2_suspend,
|
||||
.resume = bnx2_resume,
|
||||
};
|
||||
|
||||
static int __init bnx2_init(void)
|
||||
|
|
|
@ -3841,12 +3841,12 @@ struct bnx2 {
|
|||
struct status_block *status_blk;
|
||||
u32 last_status_idx;
|
||||
|
||||
atomic_t tx_avail_bd;
|
||||
struct tx_bd *tx_desc_ring;
|
||||
struct sw_bd *tx_buf_ring;
|
||||
u32 tx_prod_bseq;
|
||||
u16 tx_prod;
|
||||
u16 tx_cons;
|
||||
int tx_ring_size;
|
||||
|
||||
#ifdef BCM_VLAN
|
||||
struct vlan_group *vlgrp;
|
||||
|
@ -3872,8 +3872,10 @@ struct bnx2 {
|
|||
char *name;
|
||||
|
||||
int timer_interval;
|
||||
int current_interval;
|
||||
struct timer_list timer;
|
||||
struct work_struct reset_task;
|
||||
int in_reset_task;
|
||||
|
||||
/* Used to synchronize phy accesses. */
|
||||
spinlock_t phy_lock;
|
||||
|
@ -3927,7 +3929,6 @@ struct bnx2 {
|
|||
u16 fw_wr_seq;
|
||||
u16 fw_drv_pulse_wr_seq;
|
||||
|
||||
int tx_ring_size;
|
||||
dma_addr_t tx_desc_mapping;
|
||||
|
||||
|
||||
|
@ -3985,7 +3986,7 @@ struct bnx2 {
|
|||
#define PHY_LOOPBACK 2
|
||||
|
||||
u8 serdes_an_pending;
|
||||
#define SERDES_AN_TIMEOUT (2 * HZ)
|
||||
#define SERDES_AN_TIMEOUT (HZ / 3)
|
||||
|
||||
u8 mac_addr[8];
|
||||
|
||||
|
@ -4171,6 +4172,9 @@ struct fw_info {
|
|||
|
||||
#define BNX2_PORT_HW_CFG_MAC_LOWER 0x00000054
|
||||
#define BNX2_PORT_HW_CFG_CONFIG 0x00000058
|
||||
#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK 0x001f0000
|
||||
#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN 0x00000000
|
||||
#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G 0x00030000
|
||||
|
||||
#define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER 0x00000068
|
||||
#define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER 0x0000006c
|
||||
|
|
|
@ -2419,22 +2419,19 @@ out:
|
|||
return 0;
|
||||
}
|
||||
|
||||
int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype)
|
||||
int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev)
|
||||
{
|
||||
struct bonding *bond = dev->priv;
|
||||
struct slave *slave = NULL;
|
||||
int ret = NET_RX_DROP;
|
||||
|
||||
if (!(dev->flags & IFF_MASTER)) {
|
||||
if (!(dev->flags & IFF_MASTER))
|
||||
goto out;
|
||||
}
|
||||
|
||||
read_lock(&bond->lock);
|
||||
slave = bond_get_slave_by_dev((struct bonding *)dev->priv,
|
||||
skb->real_dev);
|
||||
if (slave == NULL) {
|
||||
slave = bond_get_slave_by_dev((struct bonding *)dev->priv, orig_dev);
|
||||
if (!slave)
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
bond_3ad_rx_indication((struct lacpdu *) skb->data, slave, skb->len);
|
||||
|
||||
|
|
|
@ -295,6 +295,6 @@ void bond_3ad_adapter_duplex_changed(struct slave *slave);
|
|||
void bond_3ad_handle_link_change(struct slave *slave, char link);
|
||||
int bond_3ad_get_active_agg_info(struct bonding *bond, struct ad_info *ad_info);
|
||||
int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev);
|
||||
int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype);
|
||||
int bond_3ad_lacpdu_recv(struct sk_buff *skb, struct net_device *dev, struct packet_type* ptype, struct net_device *orig_dev);
|
||||
#endif //__BOND_3AD_H__
|
||||
|
||||
|
|
|
@ -354,15 +354,14 @@ static void rlb_update_entry_from_arp(struct bonding *bond, struct arp_pkt *arp)
|
|||
_unlock_rx_hashtbl(bond);
|
||||
}
|
||||
|
||||
static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype)
|
||||
static int rlb_arp_recv(struct sk_buff *skb, struct net_device *bond_dev, struct packet_type *ptype, struct net_device *orig_dev)
|
||||
{
|
||||
struct bonding *bond = bond_dev->priv;
|
||||
struct arp_pkt *arp = (struct arp_pkt *)skb->data;
|
||||
int res = NET_RX_DROP;
|
||||
|
||||
if (!(bond_dev->flags & IFF_MASTER)) {
|
||||
if (!(bond_dev->flags & IFF_MASTER))
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!arp) {
|
||||
dprintk("Packet has no ARP data\n");
|
||||
|
|
|
@ -98,7 +98,7 @@ static char bcast_addr[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
|
|||
|
||||
static char bpq_eth_addr[6];
|
||||
|
||||
static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *);
|
||||
static int bpq_rcv(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *);
|
||||
static int bpq_device_event(struct notifier_block *, unsigned long, void *);
|
||||
static const char *bpq_print_ethaddr(const unsigned char *);
|
||||
|
||||
|
@ -165,7 +165,7 @@ static inline int dev_is_ethdev(struct net_device *dev)
|
|||
/*
|
||||
* Receive an AX.25 frame via an ethernet interface.
|
||||
*/
|
||||
static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype)
|
||||
static int bpq_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
|
||||
{
|
||||
int len;
|
||||
char * ptr;
|
||||
|
|
|
@ -1657,7 +1657,6 @@ ppp_receive_nonmp_frame(struct ppp *ppp, struct sk_buff *skb)
|
|||
skb->dev = ppp->dev;
|
||||
skb->protocol = htons(npindex_to_ethertype[npi]);
|
||||
skb->mac.raw = skb->data;
|
||||
skb->input_dev = ppp->dev;
|
||||
netif_rx(skb);
|
||||
ppp->dev->last_rx = jiffies;
|
||||
}
|
||||
|
|
|
@ -377,7 +377,8 @@ abort_kfree:
|
|||
***********************************************************************/
|
||||
static int pppoe_rcv(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
struct packet_type *pt)
|
||||
struct packet_type *pt,
|
||||
struct net_device *orig_dev)
|
||||
|
||||
{
|
||||
struct pppoe_hdr *ph;
|
||||
|
@ -426,7 +427,8 @@ out:
|
|||
***********************************************************************/
|
||||
static int pppoe_disc_rcv(struct sk_buff *skb,
|
||||
struct net_device *dev,
|
||||
struct packet_type *pt)
|
||||
struct packet_type *pt,
|
||||
struct net_device *orig_dev)
|
||||
|
||||
{
|
||||
struct pppoe_hdr *ph;
|
||||
|
|
|
@ -1429,6 +1429,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
{
|
||||
struct rr_private *rrpriv = netdev_priv(dev);
|
||||
struct rr_regs __iomem *regs = rrpriv->regs;
|
||||
struct hippi_cb *hcb = (struct hippi_cb *) skb->cb;
|
||||
struct ring_ctrl *txctrl;
|
||||
unsigned long flags;
|
||||
u32 index, len = skb->len;
|
||||
|
@ -1460,7 +1461,7 @@ static int rr_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
ifield = (u32 *)skb_push(skb, 8);
|
||||
|
||||
ifield[0] = 0;
|
||||
ifield[1] = skb->private.ifield;
|
||||
ifield[1] = hcb->ifield;
|
||||
|
||||
/*
|
||||
* We don't need the lock before we are actually going to start
|
||||
|
|
|
@ -156,52 +156,6 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
|
||||
SHAPERCB(skb)->shapelen= shaper_clocks(shaper,skb);
|
||||
|
||||
#ifdef SHAPER_COMPLEX /* and broken.. */
|
||||
|
||||
while(ptr && ptr!=(struct sk_buff *)&shaper->sendq)
|
||||
{
|
||||
if(ptr->pri<skb->pri
|
||||
&& jiffies - SHAPERCB(ptr)->shapeclock < SHAPER_MAXSLIP)
|
||||
{
|
||||
struct sk_buff *tmp=ptr->prev;
|
||||
|
||||
/*
|
||||
* It goes before us therefore we slip the length
|
||||
* of the new frame.
|
||||
*/
|
||||
|
||||
SHAPERCB(ptr)->shapeclock+=SHAPERCB(skb)->shapelen;
|
||||
SHAPERCB(ptr)->shapelatency+=SHAPERCB(skb)->shapelen;
|
||||
|
||||
/*
|
||||
* The packet may have slipped so far back it
|
||||
* fell off.
|
||||
*/
|
||||
if(SHAPERCB(ptr)->shapelatency > SHAPER_LATENCY)
|
||||
{
|
||||
skb_unlink(ptr);
|
||||
dev_kfree_skb(ptr);
|
||||
}
|
||||
ptr=tmp;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if(ptr==NULL || ptr==(struct sk_buff *)&shaper->sendq)
|
||||
skb_queue_head(&shaper->sendq,skb);
|
||||
else
|
||||
{
|
||||
struct sk_buff *tmp;
|
||||
/*
|
||||
* Set the packet clock out time according to the
|
||||
* frames ahead. Im sure a bit of thought could drop
|
||||
* this loop.
|
||||
*/
|
||||
for(tmp=skb_peek(&shaper->sendq); tmp!=NULL && tmp!=ptr; tmp=tmp->next)
|
||||
SHAPERCB(skb)->shapeclock+=tmp->shapelen;
|
||||
skb_append(ptr,skb);
|
||||
}
|
||||
#else
|
||||
{
|
||||
struct sk_buff *tmp;
|
||||
/*
|
||||
|
@ -220,7 +174,7 @@ static int shaper_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
} else
|
||||
skb_queue_tail(&shaper->sendq, skb);
|
||||
}
|
||||
#endif
|
||||
|
||||
if(sh_debug)
|
||||
printk("Frame queued.\n");
|
||||
if(skb_queue_len(&shaper->sendq)>SHAPER_QLEN)
|
||||
|
@ -302,7 +256,7 @@ static void shaper_kick(struct shaper *shaper)
|
|||
* Pull the frame and get interrupts back on.
|
||||
*/
|
||||
|
||||
skb_unlink(skb);
|
||||
skb_unlink(skb, &shaper->sendq);
|
||||
if (shaper->recovery <
|
||||
SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen)
|
||||
shaper->recovery = SHAPERCB(skb)->shapeclock + SHAPERCB(skb)->shapelen;
|
||||
|
|
|
@ -340,41 +340,92 @@ static struct {
|
|||
|
||||
static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
|
||||
spin_lock_bh(&tp->indirect_lock);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
|
||||
spin_unlock_bh(&tp->indirect_lock);
|
||||
} else {
|
||||
writel(val, tp->regs + off);
|
||||
if ((tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) != 0)
|
||||
readl(tp->regs + off);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tp->indirect_lock, flags);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
|
||||
spin_unlock_irqrestore(&tp->indirect_lock, flags);
|
||||
}
|
||||
|
||||
static void tg3_write_flush_reg32(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
writel(val, tp->regs + off);
|
||||
readl(tp->regs + off);
|
||||
}
|
||||
|
||||
static u32 tg3_read_indirect_reg32(struct tg3 *tp, u32 off)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&tp->indirect_lock, flags);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
|
||||
pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val);
|
||||
spin_unlock_irqrestore(&tp->indirect_lock, flags);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void tg3_write_indirect_mbox(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
unsigned long flags;
|
||||
|
||||
if (off == (MAILBOX_RCVRET_CON_IDX_0 + TG3_64BIT_REG_LOW)) {
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_RCV_RET_RING_CON_IDX +
|
||||
TG3_64BIT_REG_LOW, val);
|
||||
return;
|
||||
}
|
||||
if (off == (MAILBOX_RCV_STD_PROD_IDX + TG3_64BIT_REG_LOW)) {
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_STD_RING_PROD_IDX +
|
||||
TG3_64BIT_REG_LOW, val);
|
||||
return;
|
||||
}
|
||||
|
||||
spin_lock_irqsave(&tp->indirect_lock, flags);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
|
||||
spin_unlock_irqrestore(&tp->indirect_lock, flags);
|
||||
|
||||
/* In indirect mode when disabling interrupts, we also need
|
||||
* to clear the interrupt bit in the GRC local ctrl register.
|
||||
*/
|
||||
if ((off == (MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW)) &&
|
||||
(val == 0x1)) {
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MISC_LOCAL_CTRL,
|
||||
tp->grc_local_ctrl|GRC_LCLCTRL_CLEARINT);
|
||||
}
|
||||
}
|
||||
|
||||
static u32 tg3_read_indirect_mbox(struct tg3 *tp, u32 off)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 val;
|
||||
|
||||
spin_lock_irqsave(&tp->indirect_lock, flags);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off + 0x5600);
|
||||
pci_read_config_dword(tp->pdev, TG3PCI_REG_DATA, &val);
|
||||
spin_unlock_irqrestore(&tp->indirect_lock, flags);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void _tw32_flush(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) {
|
||||
spin_lock_bh(&tp->indirect_lock);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_BASE_ADDR, off);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_REG_DATA, val);
|
||||
spin_unlock_bh(&tp->indirect_lock);
|
||||
} else {
|
||||
void __iomem *dest = tp->regs + off;
|
||||
writel(val, dest);
|
||||
readl(dest); /* always flush PCI write */
|
||||
}
|
||||
tp->write32(tp, off, val);
|
||||
if (!(tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) &&
|
||||
!(tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG) &&
|
||||
!(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
|
||||
tp->read32(tp, off); /* flush */
|
||||
}
|
||||
|
||||
static inline void _tw32_rx_mbox(struct tg3 *tp, u32 off, u32 val)
|
||||
static inline void tw32_mailbox_flush(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
void __iomem *mbox = tp->regs + off;
|
||||
writel(val, mbox);
|
||||
if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)
|
||||
readl(mbox);
|
||||
tp->write32_mbox(tp, off, val);
|
||||
if (!(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER) &&
|
||||
!(tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND))
|
||||
tp->read32_mbox(tp, off);
|
||||
}
|
||||
|
||||
static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
|
||||
static void tg3_write32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
void __iomem *mbox = tp->regs + off;
|
||||
writel(val, mbox);
|
||||
|
@ -384,46 +435,57 @@ static inline void _tw32_tx_mbox(struct tg3 *tp, u32 off, u32 val)
|
|||
readl(mbox);
|
||||
}
|
||||
|
||||
#define tw32_mailbox(reg, val) writel(((val) & 0xffffffff), tp->regs + (reg))
|
||||
#define tw32_rx_mbox(reg, val) _tw32_rx_mbox(tp, reg, val)
|
||||
#define tw32_tx_mbox(reg, val) _tw32_tx_mbox(tp, reg, val)
|
||||
static void tg3_write32(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
writel(val, tp->regs + off);
|
||||
}
|
||||
|
||||
#define tw32(reg,val) tg3_write_indirect_reg32(tp,(reg),(val))
|
||||
static u32 tg3_read32(struct tg3 *tp, u32 off)
|
||||
{
|
||||
return (readl(tp->regs + off));
|
||||
}
|
||||
|
||||
#define tw32_mailbox(reg, val) tp->write32_mbox(tp, reg, val)
|
||||
#define tw32_mailbox_f(reg, val) tw32_mailbox_flush(tp, (reg), (val))
|
||||
#define tw32_rx_mbox(reg, val) tp->write32_rx_mbox(tp, reg, val)
|
||||
#define tw32_tx_mbox(reg, val) tp->write32_tx_mbox(tp, reg, val)
|
||||
#define tr32_mailbox(reg) tp->read32_mbox(tp, reg)
|
||||
|
||||
#define tw32(reg,val) tp->write32(tp, reg, val)
|
||||
#define tw32_f(reg,val) _tw32_flush(tp,(reg),(val))
|
||||
#define tw16(reg,val) writew(((val) & 0xffff), tp->regs + (reg))
|
||||
#define tw8(reg,val) writeb(((val) & 0xff), tp->regs + (reg))
|
||||
#define tr32(reg) readl(tp->regs + (reg))
|
||||
#define tr16(reg) readw(tp->regs + (reg))
|
||||
#define tr8(reg) readb(tp->regs + (reg))
|
||||
#define tr32(reg) tp->read32(tp, reg)
|
||||
|
||||
static void tg3_write_mem(struct tg3 *tp, u32 off, u32 val)
|
||||
{
|
||||
spin_lock_bh(&tp->indirect_lock);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tp->indirect_lock, flags);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
|
||||
|
||||
/* Always leave this as zero. */
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
spin_unlock_bh(&tp->indirect_lock);
|
||||
spin_unlock_irqrestore(&tp->indirect_lock, flags);
|
||||
}
|
||||
|
||||
static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
|
||||
{
|
||||
spin_lock_bh(&tp->indirect_lock);
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave(&tp->indirect_lock, flags);
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, off);
|
||||
pci_read_config_dword(tp->pdev, TG3PCI_MEM_WIN_DATA, val);
|
||||
|
||||
/* Always leave this as zero. */
|
||||
pci_write_config_dword(tp->pdev, TG3PCI_MEM_WIN_BASE_ADDR, 0);
|
||||
spin_unlock_bh(&tp->indirect_lock);
|
||||
spin_unlock_irqrestore(&tp->indirect_lock, flags);
|
||||
}
|
||||
|
||||
static void tg3_disable_ints(struct tg3 *tp)
|
||||
{
|
||||
tw32(TG3PCI_MISC_HOST_CTRL,
|
||||
(tp->misc_host_ctrl | MISC_HOST_CTRL_MASK_PCI_INT));
|
||||
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
|
||||
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
|
||||
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001);
|
||||
}
|
||||
|
||||
static inline void tg3_cond_int(struct tg3 *tp)
|
||||
|
@ -439,9 +501,8 @@ static void tg3_enable_ints(struct tg3 *tp)
|
|||
|
||||
tw32(TG3PCI_MISC_HOST_CTRL,
|
||||
(tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
|
||||
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
||||
(tp->last_tag << 24));
|
||||
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
|
||||
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
||||
(tp->last_tag << 24));
|
||||
tg3_cond_int(tp);
|
||||
}
|
||||
|
||||
|
@ -472,8 +533,6 @@ static inline unsigned int tg3_has_work(struct tg3 *tp)
|
|||
*/
|
||||
static void tg3_restart_ints(struct tg3 *tp)
|
||||
{
|
||||
tw32(TG3PCI_MISC_HOST_CTRL,
|
||||
(tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT));
|
||||
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
||||
tp->last_tag << 24);
|
||||
mmiowb();
|
||||
|
@ -3278,9 +3337,8 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
|
|||
/* No work, shared interrupt perhaps? re-enable
|
||||
* interrupts, and flush that PCI write
|
||||
*/
|
||||
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
||||
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
||||
0x00000000);
|
||||
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
|
||||
}
|
||||
} else { /* shared interrupt */
|
||||
handled = 0;
|
||||
|
@ -3323,9 +3381,8 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r
|
|||
/* no work, shared interrupt perhaps? re-enable
|
||||
* interrupts, and flush that PCI write
|
||||
*/
|
||||
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
||||
tp->last_tag << 24);
|
||||
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
|
||||
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW,
|
||||
tp->last_tag << 24);
|
||||
}
|
||||
} else { /* shared interrupt */
|
||||
handled = 0;
|
||||
|
@ -4216,7 +4273,7 @@ static void tg3_stop_fw(struct tg3 *);
|
|||
static int tg3_chip_reset(struct tg3 *tp)
|
||||
{
|
||||
u32 val;
|
||||
u32 flags_save;
|
||||
void (*write_op)(struct tg3 *, u32, u32);
|
||||
int i;
|
||||
|
||||
if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
|
||||
|
@ -4228,8 +4285,9 @@ static int tg3_chip_reset(struct tg3 *tp)
|
|||
* fun things. So, temporarily disable the 5701
|
||||
* hardware workaround, while we do the reset.
|
||||
*/
|
||||
flags_save = tp->tg3_flags;
|
||||
tp->tg3_flags &= ~TG3_FLAG_5701_REG_WRITE_BUG;
|
||||
write_op = tp->write32;
|
||||
if (write_op == tg3_write_flush_reg32)
|
||||
tp->write32 = tg3_write32;
|
||||
|
||||
/* do the reset */
|
||||
val = GRC_MISC_CFG_CORECLK_RESET;
|
||||
|
@ -4248,8 +4306,8 @@ static int tg3_chip_reset(struct tg3 *tp)
|
|||
val |= GRC_MISC_CFG_KEEP_GPHY_POWER;
|
||||
tw32(GRC_MISC_CFG, val);
|
||||
|
||||
/* restore 5701 hardware bug workaround flag */
|
||||
tp->tg3_flags = flags_save;
|
||||
/* restore 5701 hardware bug workaround write method */
|
||||
tp->write32 = write_op;
|
||||
|
||||
/* Unfortunately, we have to delay before the PCI read back.
|
||||
* Some 575X chips even will not respond to a PCI cfg access
|
||||
|
@ -4635,7 +4693,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
|
|||
int cpu_scratch_size, struct fw_info *info)
|
||||
{
|
||||
int err, i;
|
||||
u32 orig_tg3_flags = tp->tg3_flags;
|
||||
void (*write_op)(struct tg3 *, u32, u32);
|
||||
|
||||
if (cpu_base == TX_CPU_BASE &&
|
||||
|
@ -4651,11 +4708,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
|
|||
else
|
||||
write_op = tg3_write_indirect_reg32;
|
||||
|
||||
/* Force use of PCI config space for indirect register
|
||||
* write calls.
|
||||
*/
|
||||
tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG;
|
||||
|
||||
/* It is possible that bootcode is still loading at this point.
|
||||
* Get the nvram lock first before halting the cpu.
|
||||
*/
|
||||
|
@ -4691,7 +4743,6 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b
|
|||
err = 0;
|
||||
|
||||
out:
|
||||
tp->tg3_flags = orig_tg3_flags;
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -5808,8 +5859,7 @@ static int tg3_reset_hw(struct tg3 *tp)
|
|||
tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl);
|
||||
udelay(100);
|
||||
|
||||
tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
|
||||
tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
|
||||
tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0);
|
||||
tp->last_tag = 0;
|
||||
|
||||
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) {
|
||||
|
@ -6198,7 +6248,8 @@ static int tg3_test_interrupt(struct tg3 *tp)
|
|||
HOSTCC_MODE_NOW);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
int_mbox = tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW);
|
||||
int_mbox = tr32_mailbox(MAILBOX_INTERRUPT_0 +
|
||||
TG3_64BIT_REG_LOW);
|
||||
if (int_mbox != 0)
|
||||
break;
|
||||
msleep(10);
|
||||
|
@ -6598,10 +6649,10 @@ static int tg3_open(struct net_device *dev)
|
|||
|
||||
/* Mailboxes */
|
||||
printk("DEBUG: SNDHOST_PROD[%08x%08x] SNDNIC_PROD[%08x%08x]\n",
|
||||
tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0),
|
||||
tr32(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4),
|
||||
tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0),
|
||||
tr32(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4));
|
||||
tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + 0x0),
|
||||
tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + 0x4),
|
||||
tr32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + 0x0),
|
||||
tr32_mailbox(MAILBOX_SNDNIC_PROD_IDX_0 + 0x4));
|
||||
|
||||
/* NIC side send descriptors. */
|
||||
for (i = 0; i < 6; i++) {
|
||||
|
@ -7901,7 +7952,7 @@ static int tg3_test_loopback(struct tg3 *tp)
|
|||
num_pkts++;
|
||||
|
||||
tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx);
|
||||
tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
|
||||
tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW);
|
||||
|
||||
udelay(10);
|
||||
|
||||
|
@ -9153,14 +9204,6 @@ static int __devinit tg3_is_sun_570X(struct tg3 *tp)
|
|||
static int __devinit tg3_get_invariants(struct tg3 *tp)
|
||||
{
|
||||
static struct pci_device_id write_reorder_chipsets[] = {
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82801AA_8) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82801AB_8) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82801BA_11) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL,
|
||||
PCI_DEVICE_ID_INTEL_82801BA_6) },
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_AMD,
|
||||
PCI_DEVICE_ID_AMD_FE_GATE_700C) },
|
||||
{ },
|
||||
|
@ -9177,7 +9220,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
|||
tp->tg3_flags2 |= TG3_FLG2_SUN_570X;
|
||||
#endif
|
||||
|
||||
/* If we have an AMD 762 or Intel ICH/ICH0/ICH2 chipset, write
|
||||
/* If we have an AMD 762 chipset, write
|
||||
* reordering to the mailbox registers done by the host
|
||||
* controller can cause major troubles. We read back from
|
||||
* every mailbox register write to force the writes to be
|
||||
|
@ -9215,6 +9258,69 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
|||
if (tp->pci_chip_rev_id == CHIPREV_ID_5752_A0_HW)
|
||||
tp->pci_chip_rev_id = CHIPREV_ID_5752_A0;
|
||||
|
||||
/* If we have 5702/03 A1 or A2 on certain ICH chipsets,
|
||||
* we need to disable memory and use config. cycles
|
||||
* only to access all registers. The 5702/03 chips
|
||||
* can mistakenly decode the special cycles from the
|
||||
* ICH chipsets as memory write cycles, causing corruption
|
||||
* of register and memory space. Only certain ICH bridges
|
||||
* will drive special cycles with non-zero data during the
|
||||
* address phase which can fall within the 5703's address
|
||||
* range. This is not an ICH bug as the PCI spec allows
|
||||
* non-zero address during special cycles. However, only
|
||||
* these ICH bridges are known to drive non-zero addresses
|
||||
* during special cycles.
|
||||
*
|
||||
* Since special cycles do not cross PCI bridges, we only
|
||||
* enable this workaround if the 5703 is on the secondary
|
||||
* bus of these ICH bridges.
|
||||
*/
|
||||
if ((tp->pci_chip_rev_id == CHIPREV_ID_5703_A1) ||
|
||||
(tp->pci_chip_rev_id == CHIPREV_ID_5703_A2)) {
|
||||
static struct tg3_dev_id {
|
||||
u32 vendor;
|
||||
u32 device;
|
||||
u32 rev;
|
||||
} ich_chipsets[] = {
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_8,
|
||||
PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_8,
|
||||
PCI_ANY_ID },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_11,
|
||||
0xa },
|
||||
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_6,
|
||||
PCI_ANY_ID },
|
||||
{ },
|
||||
};
|
||||
struct tg3_dev_id *pci_id = &ich_chipsets[0];
|
||||
struct pci_dev *bridge = NULL;
|
||||
|
||||
while (pci_id->vendor != 0) {
|
||||
bridge = pci_get_device(pci_id->vendor, pci_id->device,
|
||||
bridge);
|
||||
if (!bridge) {
|
||||
pci_id++;
|
||||
continue;
|
||||
}
|
||||
if (pci_id->rev != PCI_ANY_ID) {
|
||||
u8 rev;
|
||||
|
||||
pci_read_config_byte(bridge, PCI_REVISION_ID,
|
||||
&rev);
|
||||
if (rev > pci_id->rev)
|
||||
continue;
|
||||
}
|
||||
if (bridge->subordinate &&
|
||||
(bridge->subordinate->number ==
|
||||
tp->pdev->bus->number)) {
|
||||
|
||||
tp->tg3_flags2 |= TG3_FLG2_ICH_WORKAROUND;
|
||||
pci_dev_put(bridge);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find msi capability. */
|
||||
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
|
||||
tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
|
||||
|
@ -9302,6 +9408,12 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
|||
}
|
||||
}
|
||||
|
||||
/* 5700 BX chips need to have their TX producer index mailboxes
|
||||
* written twice to workaround a bug.
|
||||
*/
|
||||
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX)
|
||||
tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
|
||||
|
||||
/* Back to back register writes can cause problems on this chip,
|
||||
* the workaround is to read back all reg writes except those to
|
||||
* mailbox regs. See tg3_write_indirect_reg32().
|
||||
|
@ -9325,6 +9437,43 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
|||
pci_write_config_dword(tp->pdev, TG3PCI_PCISTATE, pci_state_reg);
|
||||
}
|
||||
|
||||
/* Default fast path register access methods */
|
||||
tp->read32 = tg3_read32;
|
||||
tp->write32 = tg3_write32;
|
||||
tp->read32_mbox = tg3_read32;
|
||||
tp->write32_mbox = tg3_write32;
|
||||
tp->write32_tx_mbox = tg3_write32;
|
||||
tp->write32_rx_mbox = tg3_write32;
|
||||
|
||||
/* Various workaround register access methods */
|
||||
if (tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG)
|
||||
tp->write32 = tg3_write_indirect_reg32;
|
||||
else if (tp->tg3_flags & TG3_FLAG_5701_REG_WRITE_BUG)
|
||||
tp->write32 = tg3_write_flush_reg32;
|
||||
|
||||
if ((tp->tg3_flags & TG3_FLAG_TXD_MBOX_HWBUG) ||
|
||||
(tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)) {
|
||||
tp->write32_tx_mbox = tg3_write32_tx_mbox;
|
||||
if (tp->tg3_flags & TG3_FLAG_MBOX_WRITE_REORDER)
|
||||
tp->write32_rx_mbox = tg3_write_flush_reg32;
|
||||
}
|
||||
|
||||
if (tp->tg3_flags2 & TG3_FLG2_ICH_WORKAROUND) {
|
||||
tp->read32 = tg3_read_indirect_reg32;
|
||||
tp->write32 = tg3_write_indirect_reg32;
|
||||
tp->read32_mbox = tg3_read_indirect_mbox;
|
||||
tp->write32_mbox = tg3_write_indirect_mbox;
|
||||
tp->write32_tx_mbox = tg3_write_indirect_mbox;
|
||||
tp->write32_rx_mbox = tg3_write_indirect_mbox;
|
||||
|
||||
iounmap(tp->regs);
|
||||
tp->regs = 0;
|
||||
|
||||
pci_read_config_word(tp->pdev, PCI_COMMAND, &pci_cmd);
|
||||
pci_cmd &= ~PCI_COMMAND_MEMORY;
|
||||
pci_write_config_word(tp->pdev, PCI_COMMAND, pci_cmd);
|
||||
}
|
||||
|
||||
/* Get eeprom hw config before calling tg3_set_power_state().
|
||||
* In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be
|
||||
* determined before calling tg3_set_power_state() so that
|
||||
|
@ -9539,14 +9688,6 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
|
|||
else
|
||||
tp->tg3_flags &= ~TG3_FLAG_POLL_SERDES;
|
||||
|
||||
/* 5700 BX chips need to have their TX producer index mailboxes
|
||||
* written twice to workaround a bug.
|
||||
*/
|
||||
if (GET_CHIP_REV(tp->pci_chip_rev_id) == CHIPREV_5700_BX)
|
||||
tp->tg3_flags |= TG3_FLAG_TXD_MBOX_HWBUG;
|
||||
else
|
||||
tp->tg3_flags &= ~TG3_FLAG_TXD_MBOX_HWBUG;
|
||||
|
||||
/* It seems all chips can get confused if TX buffers
|
||||
* straddle the 4GB address boundary in some cases.
|
||||
*/
|
||||
|
@ -10469,7 +10610,10 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
|
|||
return 0;
|
||||
|
||||
err_out_iounmap:
|
||||
iounmap(tp->regs);
|
||||
if (tp->regs) {
|
||||
iounmap(tp->regs);
|
||||
tp->regs = 0;
|
||||
}
|
||||
|
||||
err_out_free_dev:
|
||||
free_netdev(dev);
|
||||
|
@ -10491,7 +10635,10 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
|
|||
struct tg3 *tp = netdev_priv(dev);
|
||||
|
||||
unregister_netdev(dev);
|
||||
iounmap(tp->regs);
|
||||
if (tp->regs) {
|
||||
iounmap(tp->regs);
|
||||
tp->regs = 0;
|
||||
}
|
||||
free_netdev(dev);
|
||||
pci_release_regions(pdev);
|
||||
pci_disable_device(pdev);
|
||||
|
|
|
@ -2049,6 +2049,11 @@ struct tg3 {
|
|||
spinlock_t lock;
|
||||
spinlock_t indirect_lock;
|
||||
|
||||
u32 (*read32) (struct tg3 *, u32);
|
||||
void (*write32) (struct tg3 *, u32, u32);
|
||||
u32 (*read32_mbox) (struct tg3 *, u32);
|
||||
void (*write32_mbox) (struct tg3 *, u32,
|
||||
u32);
|
||||
void __iomem *regs;
|
||||
struct net_device *dev;
|
||||
struct pci_dev *pdev;
|
||||
|
@ -2060,6 +2065,8 @@ struct tg3 {
|
|||
u32 msg_enable;
|
||||
|
||||
/* begin "tx thread" cacheline section */
|
||||
void (*write32_tx_mbox) (struct tg3 *, u32,
|
||||
u32);
|
||||
u32 tx_prod;
|
||||
u32 tx_cons;
|
||||
u32 tx_pending;
|
||||
|
@ -2071,6 +2078,8 @@ struct tg3 {
|
|||
dma_addr_t tx_desc_mapping;
|
||||
|
||||
/* begin "rx thread" cacheline section */
|
||||
void (*write32_rx_mbox) (struct tg3 *, u32,
|
||||
u32);
|
||||
u32 rx_rcb_ptr;
|
||||
u32 rx_std_ptr;
|
||||
u32 rx_jumbo_ptr;
|
||||
|
@ -2165,6 +2174,7 @@ struct tg3 {
|
|||
#define TG3_FLG2_ANY_SERDES (TG3_FLG2_PHY_SERDES | \
|
||||
TG3_FLG2_MII_SERDES)
|
||||
#define TG3_FLG2_PARALLEL_DETECT 0x01000000
|
||||
#define TG3_FLG2_ICH_WORKAROUND 0x02000000
|
||||
|
||||
u32 split_mode_max_reqs;
|
||||
#define SPLIT_MODE_5704_MAX_REQ 3
|
||||
|
|
|
@ -61,7 +61,7 @@ static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
|
|||
|
||||
|
||||
static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
struct packet_type *p)
|
||||
struct packet_type *p, struct net_device *orig_dev)
|
||||
{
|
||||
hdlc_device *hdlc = dev_to_hdlc(dev);
|
||||
if (hdlc->proto.netif_rx)
|
||||
|
|
|
@ -86,7 +86,7 @@ static __inline__ int dev_is_ethdev(struct net_device *dev)
|
|||
/*
|
||||
* Receive a LAPB frame via an ethernet interface.
|
||||
*/
|
||||
static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype)
|
||||
static int lapbeth_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *ptype, struct net_device *orig_dev)
|
||||
{
|
||||
int len, err;
|
||||
struct lapbethdev *lapbeth;
|
||||
|
|
|
@ -445,7 +445,7 @@ void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags);
|
|||
void s508_s514_lock(sdla_t *card, unsigned long *smp_flags);
|
||||
|
||||
unsigned short calc_checksum (char *, int);
|
||||
static int setup_fr_header(struct sk_buff** skb,
|
||||
static int setup_fr_header(struct sk_buff *skb,
|
||||
struct net_device* dev, char op_mode);
|
||||
|
||||
|
||||
|
@ -1372,7 +1372,7 @@ static int if_send(struct sk_buff* skb, struct net_device* dev)
|
|||
/* Move the if_header() code to here. By inserting frame
|
||||
* relay header in if_header() we would break the
|
||||
* tcpdump and other packet sniffers */
|
||||
chan->fr_header_len = setup_fr_header(&skb,dev,chan->common.usedby);
|
||||
chan->fr_header_len = setup_fr_header(skb,dev,chan->common.usedby);
|
||||
if (chan->fr_header_len < 0 ){
|
||||
++chan->ifstats.tx_dropped;
|
||||
++card->wandev.stats.tx_dropped;
|
||||
|
@ -1597,8 +1597,6 @@ static int setup_for_delayed_transmit(struct net_device* dev,
|
|||
return 1;
|
||||
}
|
||||
|
||||
skb_unlink(skb);
|
||||
|
||||
chan->transmit_length = len;
|
||||
chan->delay_skb = skb;
|
||||
|
||||
|
@ -4871,18 +4869,15 @@ static void unconfig_fr (sdla_t *card)
|
|||
}
|
||||
}
|
||||
|
||||
static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev,
|
||||
static int setup_fr_header(struct sk_buff *skb, struct net_device* dev,
|
||||
char op_mode)
|
||||
{
|
||||
struct sk_buff *skb = *skb_orig;
|
||||
fr_channel_t *chan=dev->priv;
|
||||
|
||||
if (op_mode == WANPIPE){
|
||||
|
||||
if (op_mode == WANPIPE) {
|
||||
chan->fr_header[0]=Q922_UI;
|
||||
|
||||
switch (htons(skb->protocol)){
|
||||
|
||||
case ETH_P_IP:
|
||||
chan->fr_header[1]=NLPID_IP;
|
||||
break;
|
||||
|
@ -4894,16 +4889,14 @@ static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev,
|
|||
}
|
||||
|
||||
/* If we are in bridging mode, we must apply
|
||||
* an Ethernet header */
|
||||
if (op_mode == BRIDGE || op_mode == BRIDGE_NODE){
|
||||
|
||||
|
||||
* an Ethernet header
|
||||
*/
|
||||
if (op_mode == BRIDGE || op_mode == BRIDGE_NODE) {
|
||||
/* Encapsulate the packet as a bridged Ethernet frame. */
|
||||
#ifdef DEBUG
|
||||
printk(KERN_INFO "%s: encapsulating skb for frame relay\n",
|
||||
dev->name);
|
||||
#endif
|
||||
|
||||
chan->fr_header[0] = 0x03;
|
||||
chan->fr_header[1] = 0x00;
|
||||
chan->fr_header[2] = 0x80;
|
||||
|
@ -4916,7 +4909,6 @@ static int setup_fr_header(struct sk_buff **skb_orig, struct net_device* dev,
|
|||
/* Yuck. */
|
||||
skb->protocol = ETH_P_802_3;
|
||||
return 8;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -1447,7 +1447,7 @@ static void sppp_print_bytes (u_char *p, u16 len)
|
|||
* after interrupt servicing to process frames queued via netif_rx.
|
||||
*/
|
||||
|
||||
static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p)
|
||||
static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev)
|
||||
{
|
||||
if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
|
||||
return NET_RX_DROP;
|
||||
|
|
|
@ -2903,19 +2903,18 @@ static struct net_device_stats *usbnet_get_stats (struct net_device *net)
|
|||
* completion callbacks. 2.5 should have fixed those bugs...
|
||||
*/
|
||||
|
||||
static void defer_bh (struct usbnet *dev, struct sk_buff *skb)
|
||||
static void defer_bh(struct usbnet *dev, struct sk_buff *skb, struct sk_buff_head *list)
|
||||
{
|
||||
struct sk_buff_head *list = skb->list;
|
||||
unsigned long flags;
|
||||
|
||||
spin_lock_irqsave (&list->lock, flags);
|
||||
__skb_unlink (skb, list);
|
||||
spin_unlock (&list->lock);
|
||||
spin_lock (&dev->done.lock);
|
||||
__skb_queue_tail (&dev->done, skb);
|
||||
spin_lock_irqsave(&list->lock, flags);
|
||||
__skb_unlink(skb, list);
|
||||
spin_unlock(&list->lock);
|
||||
spin_lock(&dev->done.lock);
|
||||
__skb_queue_tail(&dev->done, skb);
|
||||
if (dev->done.qlen == 1)
|
||||
tasklet_schedule (&dev->bh);
|
||||
spin_unlock_irqrestore (&dev->done.lock, flags);
|
||||
tasklet_schedule(&dev->bh);
|
||||
spin_unlock_irqrestore(&dev->done.lock, flags);
|
||||
}
|
||||
|
||||
/* some work can't be done in tasklets, so we use keventd
|
||||
|
@ -3120,7 +3119,7 @@ block:
|
|||
break;
|
||||
}
|
||||
|
||||
defer_bh (dev, skb);
|
||||
defer_bh(dev, skb, &dev->rxq);
|
||||
|
||||
if (urb) {
|
||||
if (netif_running (dev->net)
|
||||
|
@ -3490,7 +3489,7 @@ static void tx_complete (struct urb *urb, struct pt_regs *regs)
|
|||
|
||||
urb->dev = NULL;
|
||||
entry->state = tx_done;
|
||||
defer_bh (dev, skb);
|
||||
defer_bh(dev, skb, &dev->txq);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
|
|
@ -86,9 +86,9 @@ static struct w1_master * w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
|
|||
|
||||
dev->driver = driver;
|
||||
|
||||
dev->groups = 23;
|
||||
dev->groups = 1;
|
||||
dev->seq = 1;
|
||||
dev->nls = netlink_kernel_create(NETLINK_W1, NULL);
|
||||
dev->nls = netlink_kernel_create(NETLINK_W1, 1, NULL, THIS_MODULE);
|
||||
if (!dev->nls) {
|
||||
printk(KERN_ERR "Failed to create new netlink socket(%u) for w1 master %s.\n",
|
||||
NETLINK_NFLOG, dev->dev.bus_id);
|
||||
|
@ -225,3 +225,5 @@ void w1_remove_master_device(struct w1_bus_master *bm)
|
|||
|
||||
EXPORT_SYMBOL(w1_add_master_device);
|
||||
EXPORT_SYMBOL(w1_remove_master_device);
|
||||
|
||||
MODULE_ALIAS_NET_PF_PROTO(PF_NETLINK, NETLINK_W1);
|
||||
|
|
|
@ -51,7 +51,7 @@ void w1_netlink_send(struct w1_master *dev, struct w1_netlink_msg *msg)
|
|||
|
||||
memcpy(data, msg, sizeof(struct w1_netlink_msg));
|
||||
|
||||
NETLINK_CB(skb).dst_groups = dev->groups;
|
||||
NETLINK_CB(skb).dst_group = dev->groups;
|
||||
netlink_broadcast(dev->nls, skb, 0, dev->groups, GFP_ATOMIC);
|
||||
|
||||
nlmsg_failure:
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
#include <linux/file.h>
|
||||
#include <linux/in.h>
|
||||
#include <linux/net.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <net/scm.h>
|
||||
#include <net/tcp_states.h>
|
||||
#include <net/ip.h>
|
||||
|
||||
#include <linux/smb_fs.h>
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
#define SO_ERROR 0x1007
|
||||
#define SO_SNDBUF 0x1001
|
||||
#define SO_RCVBUF 0x1002
|
||||
#define SO_SNDBUFFORCE 0x100a
|
||||
#define SO_RCVBUFFORCE 0x100b
|
||||
#define SO_RCVLOWAT 0x1010
|
||||
#define SO_SNDLOWAT 0x1011
|
||||
#define SO_RCVTIMEO 0x1012
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -83,7 +83,7 @@ static inline unsigned short ip_fast_csum(unsigned char * iph,
|
|||
"adcl $0, %0 ;\n"
|
||||
"notl %0 ;\n"
|
||||
"2: ;\n"
|
||||
/* Since the input registers which are loaded with iph and ipl
|
||||
/* Since the input registers which are loaded with iph and ihl
|
||||
are modified, we must also specify them as outputs, or gcc
|
||||
will assume they contain their original values. */
|
||||
: "=r" (sum), "=r" (iph), "=r" (ihl)
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -105,7 +105,7 @@ static inline unsigned short ip_fast_csum(unsigned char * iph,
|
|||
" addx %0, %3 \n"
|
||||
" .fillinsn\n"
|
||||
"2: \n"
|
||||
/* Since the input registers which are loaded with iph and ipl
|
||||
/* Since the input registers which are loaded with iph and ihl
|
||||
are modified, we must also specify them as outputs, or gcc
|
||||
will assume they contain their original values. */
|
||||
: "=&r" (sum), "=r" (iph), "=r" (ihl), "=&r" (tmpreg0), "=&r" (tmpreg1)
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -37,6 +37,8 @@ To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */
|
|||
#define SO_ERROR 0x1007 /* get error status and clear */
|
||||
#define SO_SNDBUF 0x1001 /* Send buffer size. */
|
||||
#define SO_RCVBUF 0x1002 /* Receive buffer. */
|
||||
#define SO_SNDBUFFORCE 0x100a
|
||||
#define SO_RCVBUFFORCE 0x100b
|
||||
#define SO_SNDLOWAT 0x1003 /* send low-water mark */
|
||||
#define SO_RCVLOWAT 0x1004 /* receive low-water mark */
|
||||
#define SO_SNDTIMEO 0x1005 /* send timeout */
|
||||
|
|
|
@ -16,6 +16,8 @@
|
|||
/* To add :#define SO_REUSEPORT 0x0200 */
|
||||
#define SO_SNDBUF 0x1001
|
||||
#define SO_RCVBUF 0x1002
|
||||
#define SO_SNDBUFFORCE 0x100a
|
||||
#define SO_RCVBUFFORCE 0x100b
|
||||
#define SO_SNDLOWAT 0x1003
|
||||
#define SO_RCVLOWAT 0x1004
|
||||
#define SO_SNDTIMEO 0x1005
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_RCVBUFFORCE 32
|
||||
#define SO_SNDBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#define SO_SNDBUF 0x1001
|
||||
#define SO_RCVBUF 0x1002
|
||||
#define SO_SNDBUFFORCE 0x100a
|
||||
#define SO_RCVBUFFORCE 0x100b
|
||||
#define SO_ERROR 0x1007
|
||||
#define SO_TYPE 0x1008
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#define SO_SNDBUF 0x1001
|
||||
#define SO_RCVBUF 0x1002
|
||||
#define SO_SNDBUFFORCE 0x100a
|
||||
#define SO_RCVBUFFORCE 0x100b
|
||||
#define SO_ERROR 0x1007
|
||||
#define SO_TYPE 0x1008
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -64,7 +64,7 @@ static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl)
|
|||
" adcl $0, %0\n"
|
||||
" notl %0\n"
|
||||
"2:"
|
||||
/* Since the input registers which are loaded with iph and ipl
|
||||
/* Since the input registers which are loaded with iph and ihl
|
||||
are modified, we must also specify them as outputs, or gcc
|
||||
will assume they contain their original values. */
|
||||
: "=r" (sum), "=r" (iph), "=r" (ihl)
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#define SO_BROADCAST 6
|
||||
#define SO_SNDBUF 7
|
||||
#define SO_RCVBUF 8
|
||||
#define SO_SNDBUFFORCE 32
|
||||
#define SO_RCVBUFFORCE 33
|
||||
#define SO_KEEPALIVE 9
|
||||
#define SO_OOBINLINE 10
|
||||
#define SO_NO_CHECK 11
|
||||
|
|
456
include/linux/dccp.h
Normal file
456
include/linux/dccp.h
Normal file
|
@ -0,0 +1,456 @@
|
|||
#ifndef _LINUX_DCCP_H
|
||||
#define _LINUX_DCCP_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
||||
/* Structure describing an Internet (DCCP) socket address. */
|
||||
struct sockaddr_dccp {
|
||||
__u16 sdccp_family; /* Address family */
|
||||
__u16 sdccp_port; /* Port number */
|
||||
__u32 sdccp_addr; /* Internet address */
|
||||
__u32 sdccp_service; /* Service */
|
||||
/* Pad to size of `struct sockaddr': 16 bytes . */
|
||||
__u32 sdccp_pad;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dccp_hdr - generic part of DCCP packet header
|
||||
*
|
||||
* @dccph_sport - Relevant port on the endpoint that sent this packet
|
||||
* @dccph_dport - Relevant port on the other endpoint
|
||||
* @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words
|
||||
* @dccph_ccval - Used by the HC-Sender CCID
|
||||
* @dccph_cscov - Parts of the packet that are covered by the Checksum field
|
||||
* @dccph_checksum - Internet checksum, depends on dccph_cscov
|
||||
* @dccph_x - 0 = 24 bit sequence number, 1 = 48
|
||||
* @dccph_type - packet type, see DCCP_PKT_ prefixed macros
|
||||
* @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
|
||||
*/
|
||||
struct dccp_hdr {
|
||||
__u16 dccph_sport,
|
||||
dccph_dport;
|
||||
__u8 dccph_doff;
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
__u8 dccph_cscov:4,
|
||||
dccph_ccval:4;
|
||||
#elif defined(__BIG_ENDIAN_BITFIELD)
|
||||
__u8 dccph_ccval:4,
|
||||
dccph_cscov:4;
|
||||
#else
|
||||
#error "Adjust your <asm/byteorder.h> defines"
|
||||
#endif
|
||||
__u16 dccph_checksum;
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
__u32 dccph_x:1,
|
||||
dccph_type:4,
|
||||
dccph_reserved:3,
|
||||
dccph_seq:24;
|
||||
#elif defined(__BIG_ENDIAN_BITFIELD)
|
||||
__u32 dccph_reserved:3,
|
||||
dccph_type:4,
|
||||
dccph_x:1,
|
||||
dccph_seq:24;
|
||||
#else
|
||||
#error "Adjust your <asm/byteorder.h> defines"
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dccp_hdr_ext - the low bits of a 48 bit seq packet
|
||||
*
|
||||
* @dccph_seq_low - low 24 bits of a 48 bit seq packet
|
||||
*/
|
||||
struct dccp_hdr_ext {
|
||||
__u32 dccph_seq_low;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dccp_hdr_request - Conection initiation request header
|
||||
*
|
||||
* @dccph_req_service - Service to which the client app wants to connect
|
||||
* @dccph_req_options - list of options (must be a multiple of 32 bits
|
||||
*/
|
||||
struct dccp_hdr_request {
|
||||
__u32 dccph_req_service;
|
||||
};
|
||||
/**
|
||||
* struct dccp_hdr_ack_bits - acknowledgment bits common to most packets
|
||||
*
|
||||
* @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
|
||||
* @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
|
||||
*/
|
||||
struct dccp_hdr_ack_bits {
|
||||
__u32 dccph_reserved1:8,
|
||||
dccph_ack_nr_high:24;
|
||||
__u32 dccph_ack_nr_low;
|
||||
};
|
||||
/**
|
||||
* struct dccp_hdr_response - Conection initiation response header
|
||||
*
|
||||
* @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
|
||||
* @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
|
||||
* @dccph_resp_service - Echoes the Service Code on a received DCCP-Request
|
||||
* @dccph_resp_options - list of options (must be a multiple of 32 bits
|
||||
*/
|
||||
struct dccp_hdr_response {
|
||||
struct dccp_hdr_ack_bits dccph_resp_ack;
|
||||
__u32 dccph_resp_service;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dccp_hdr_reset - Unconditionally shut down a connection
|
||||
*
|
||||
* @dccph_reset_service - Echoes the Service Code on a received DCCP-Request
|
||||
* @dccph_reset_options - list of options (must be a multiple of 32 bits
|
||||
*/
|
||||
struct dccp_hdr_reset {
|
||||
struct dccp_hdr_ack_bits dccph_reset_ack;
|
||||
__u8 dccph_reset_code,
|
||||
dccph_reset_data[3];
|
||||
};
|
||||
|
||||
enum dccp_pkt_type {
|
||||
DCCP_PKT_REQUEST = 0,
|
||||
DCCP_PKT_RESPONSE,
|
||||
DCCP_PKT_DATA,
|
||||
DCCP_PKT_ACK,
|
||||
DCCP_PKT_DATAACK,
|
||||
DCCP_PKT_CLOSEREQ,
|
||||
DCCP_PKT_CLOSE,
|
||||
DCCP_PKT_RESET,
|
||||
DCCP_PKT_SYNC,
|
||||
DCCP_PKT_SYNCACK,
|
||||
DCCP_PKT_INVALID,
|
||||
};
|
||||
|
||||
#define DCCP_NR_PKT_TYPES DCCP_PKT_INVALID
|
||||
|
||||
static inline unsigned int dccp_packet_hdr_len(const __u8 type)
|
||||
{
|
||||
if (type == DCCP_PKT_DATA)
|
||||
return 0;
|
||||
if (type == DCCP_PKT_DATAACK ||
|
||||
type == DCCP_PKT_ACK ||
|
||||
type == DCCP_PKT_SYNC ||
|
||||
type == DCCP_PKT_SYNCACK ||
|
||||
type == DCCP_PKT_CLOSE ||
|
||||
type == DCCP_PKT_CLOSEREQ)
|
||||
return sizeof(struct dccp_hdr_ack_bits);
|
||||
if (type == DCCP_PKT_REQUEST)
|
||||
return sizeof(struct dccp_hdr_request);
|
||||
if (type == DCCP_PKT_RESPONSE)
|
||||
return sizeof(struct dccp_hdr_response);
|
||||
return sizeof(struct dccp_hdr_reset);
|
||||
}
|
||||
enum dccp_reset_codes {
|
||||
DCCP_RESET_CODE_UNSPECIFIED = 0,
|
||||
DCCP_RESET_CODE_CLOSED,
|
||||
DCCP_RESET_CODE_ABORTED,
|
||||
DCCP_RESET_CODE_NO_CONNECTION,
|
||||
DCCP_RESET_CODE_PACKET_ERROR,
|
||||
DCCP_RESET_CODE_OPTION_ERROR,
|
||||
DCCP_RESET_CODE_MANDATORY_ERROR,
|
||||
DCCP_RESET_CODE_CONNECTION_REFUSED,
|
||||
DCCP_RESET_CODE_BAD_SERVICE_CODE,
|
||||
DCCP_RESET_CODE_TOO_BUSY,
|
||||
DCCP_RESET_CODE_BAD_INIT_COOKIE,
|
||||
DCCP_RESET_CODE_AGGRESSION_PENALTY,
|
||||
};
|
||||
|
||||
/* DCCP options */
|
||||
enum {
|
||||
DCCPO_PADDING = 0,
|
||||
DCCPO_MANDATORY = 1,
|
||||
DCCPO_MIN_RESERVED = 3,
|
||||
DCCPO_MAX_RESERVED = 31,
|
||||
DCCPO_NDP_COUNT = 37,
|
||||
DCCPO_ACK_VECTOR_0 = 38,
|
||||
DCCPO_ACK_VECTOR_1 = 39,
|
||||
DCCPO_TIMESTAMP = 41,
|
||||
DCCPO_TIMESTAMP_ECHO = 42,
|
||||
DCCPO_ELAPSED_TIME = 43,
|
||||
DCCPO_MAX = 45,
|
||||
DCCPO_MIN_CCID_SPECIFIC = 128,
|
||||
DCCPO_MAX_CCID_SPECIFIC = 255,
|
||||
};
|
||||
|
||||
/* DCCP features */
|
||||
enum {
|
||||
DCCPF_RESERVED = 0,
|
||||
DCCPF_SEQUENCE_WINDOW = 3,
|
||||
DCCPF_SEND_ACK_VECTOR = 6,
|
||||
DCCPF_SEND_NDP_COUNT = 7,
|
||||
/* 10-127 reserved */
|
||||
DCCPF_MIN_CCID_SPECIFIC = 128,
|
||||
DCCPF_MAX_CCID_SPECIFIC = 255,
|
||||
};
|
||||
|
||||
/* DCCP socket options */
|
||||
#define DCCP_SOCKOPT_PACKET_SIZE 1
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/in.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/workqueue.h>
|
||||
|
||||
#include <net/inet_connection_sock.h>
|
||||
#include <net/inet_timewait_sock.h>
|
||||
#include <net/sock.h>
|
||||
#include <net/tcp_states.h>
|
||||
#include <net/tcp.h>
|
||||
|
||||
enum dccp_state {
|
||||
DCCP_OPEN = TCP_ESTABLISHED,
|
||||
DCCP_REQUESTING = TCP_SYN_SENT,
|
||||
DCCP_PARTOPEN = TCP_FIN_WAIT1, /* FIXME:
|
||||
This mapping is horrible, but TCP has
|
||||
no matching state for DCCP_PARTOPEN,
|
||||
as TCP_SYN_RECV is already used by
|
||||
DCCP_RESPOND, why don't stop using TCP
|
||||
mapping of states? OK, now we don't use
|
||||
sk_stream_sendmsg anymore, so doesn't
|
||||
seem to exist any reason for us to
|
||||
do the TCP mapping here */
|
||||
DCCP_LISTEN = TCP_LISTEN,
|
||||
DCCP_RESPOND = TCP_SYN_RECV,
|
||||
DCCP_CLOSING = TCP_CLOSING,
|
||||
DCCP_TIME_WAIT = TCP_TIME_WAIT,
|
||||
DCCP_CLOSED = TCP_CLOSE,
|
||||
DCCP_MAX_STATES = TCP_MAX_STATES,
|
||||
};
|
||||
|
||||
#define DCCP_STATE_MASK 0xf
|
||||
#define DCCP_ACTION_FIN (1<<7)
|
||||
|
||||
enum {
|
||||
DCCPF_OPEN = TCPF_ESTABLISHED,
|
||||
DCCPF_REQUESTING = TCPF_SYN_SENT,
|
||||
DCCPF_PARTOPEN = TCPF_FIN_WAIT1,
|
||||
DCCPF_LISTEN = TCPF_LISTEN,
|
||||
DCCPF_RESPOND = TCPF_SYN_RECV,
|
||||
DCCPF_CLOSING = TCPF_CLOSING,
|
||||
DCCPF_TIME_WAIT = TCPF_TIME_WAIT,
|
||||
DCCPF_CLOSED = TCPF_CLOSE,
|
||||
};
|
||||
|
||||
static inline struct dccp_hdr *dccp_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct dccp_hdr *)skb->h.raw;
|
||||
}
|
||||
|
||||
static inline struct dccp_hdr_ext *dccp_hdrx(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct dccp_hdr_ext *)(skb->h.raw + sizeof(struct dccp_hdr));
|
||||
}
|
||||
|
||||
static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh)
|
||||
{
|
||||
return sizeof(*dh) + (dh->dccph_x ? sizeof(struct dccp_hdr_ext) : 0);
|
||||
}
|
||||
|
||||
static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb)
|
||||
{
|
||||
const struct dccp_hdr *dh = dccp_hdr(skb);
|
||||
return __dccp_basic_hdr_len(dh);
|
||||
}
|
||||
|
||||
static inline __u64 dccp_hdr_seq(const struct sk_buff *skb)
|
||||
{
|
||||
const struct dccp_hdr *dh = dccp_hdr(skb);
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
__u64 seq_nr = ntohl(dh->dccph_seq << 8);
|
||||
#elif defined(__BIG_ENDIAN_BITFIELD)
|
||||
__u64 seq_nr = ntohl(dh->dccph_seq);
|
||||
#else
|
||||
#error "Adjust your <asm/byteorder.h> defines"
|
||||
#endif
|
||||
|
||||
if (dh->dccph_x != 0)
|
||||
seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low);
|
||||
|
||||
return seq_nr;
|
||||
}
|
||||
|
||||
static inline struct dccp_hdr_request *dccp_hdr_request(struct sk_buff *skb)
|
||||
{
|
||||
return (struct dccp_hdr_request *)(skb->h.raw + dccp_basic_hdr_len(skb));
|
||||
}
|
||||
|
||||
static inline struct dccp_hdr_ack_bits *dccp_hdr_ack_bits(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct dccp_hdr_ack_bits *)(skb->h.raw + dccp_basic_hdr_len(skb));
|
||||
}
|
||||
|
||||
static inline u64 dccp_hdr_ack_seq(const struct sk_buff *skb)
|
||||
{
|
||||
const struct dccp_hdr_ack_bits *dhack = dccp_hdr_ack_bits(skb);
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
return (((u64)ntohl(dhack->dccph_ack_nr_high << 8)) << 32) + ntohl(dhack->dccph_ack_nr_low);
|
||||
#elif defined(__BIG_ENDIAN_BITFIELD)
|
||||
return (((u64)ntohl(dhack->dccph_ack_nr_high)) << 32) + ntohl(dhack->dccph_ack_nr_low);
|
||||
#else
|
||||
#error "Adjust your <asm/byteorder.h> defines"
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline struct dccp_hdr_response *dccp_hdr_response(struct sk_buff *skb)
|
||||
{
|
||||
return (struct dccp_hdr_response *)(skb->h.raw + dccp_basic_hdr_len(skb));
|
||||
}
|
||||
|
||||
static inline struct dccp_hdr_reset *dccp_hdr_reset(struct sk_buff *skb)
|
||||
{
|
||||
return (struct dccp_hdr_reset *)(skb->h.raw + dccp_basic_hdr_len(skb));
|
||||
}
|
||||
|
||||
static inline unsigned int __dccp_hdr_len(const struct dccp_hdr *dh)
|
||||
{
|
||||
return __dccp_basic_hdr_len(dh) +
|
||||
dccp_packet_hdr_len(dh->dccph_type);
|
||||
}
|
||||
|
||||
static inline unsigned int dccp_hdr_len(const struct sk_buff *skb)
|
||||
{
|
||||
return __dccp_hdr_len(dccp_hdr(skb));
|
||||
}
|
||||
|
||||
|
||||
/* initial values for each feature */
|
||||
#define DCCPF_INITIAL_SEQUENCE_WINDOW 100
|
||||
/* FIXME: for now we're using CCID 3 (TFRC) */
|
||||
#define DCCPF_INITIAL_CCID 3
|
||||
#define DCCPF_INITIAL_SEND_ACK_VECTOR 0
|
||||
/* FIXME: for now we're default to 1 but it should really be 0 */
|
||||
#define DCCPF_INITIAL_SEND_NDP_COUNT 1
|
||||
|
||||
#define DCCP_NDP_LIMIT 0xFFFFFF
|
||||
|
||||
/**
|
||||
* struct dccp_options - option values for a DCCP connection
|
||||
* @dccpo_sequence_window - Sequence Window Feature (section 7.5.2)
|
||||
* @dccpo_ccid - Congestion Control Id (CCID) (section 10)
|
||||
* @dccpo_send_ack_vector - Send Ack Vector Feature (section 11.5)
|
||||
* @dccpo_send_ndp_count - Send NDP Count Feature (7.7.2)
|
||||
*/
|
||||
struct dccp_options {
|
||||
__u64 dccpo_sequence_window;
|
||||
__u8 dccpo_ccid;
|
||||
__u8 dccpo_send_ack_vector;
|
||||
__u8 dccpo_send_ndp_count;
|
||||
};
|
||||
|
||||
extern void __dccp_options_init(struct dccp_options *dccpo);
|
||||
extern void dccp_options_init(struct dccp_options *dccpo);
|
||||
extern int dccp_parse_options(struct sock *sk, struct sk_buff *skb);
|
||||
|
||||
struct dccp_request_sock {
|
||||
struct inet_request_sock dreq_inet_rsk;
|
||||
__u64 dreq_iss;
|
||||
__u64 dreq_isr;
|
||||
__u32 dreq_service;
|
||||
};
|
||||
|
||||
static inline struct dccp_request_sock *dccp_rsk(const struct request_sock *req)
|
||||
{
|
||||
return (struct dccp_request_sock *)req;
|
||||
}
|
||||
|
||||
extern struct inet_timewait_death_row dccp_death_row;
|
||||
|
||||
/* Read about the ECN nonce to see why it is 253 */
|
||||
#define DCCP_MAX_ACK_VECTOR_LEN 253
|
||||
|
||||
struct dccp_options_received {
|
||||
u32 dccpor_ndp:24,
|
||||
dccpor_ack_vector_len:8;
|
||||
u32 dccpor_ack_vector_idx:10;
|
||||
/* 22 bits hole, try to pack */
|
||||
u32 dccpor_timestamp;
|
||||
u32 dccpor_timestamp_echo;
|
||||
u32 dccpor_elapsed_time;
|
||||
};
|
||||
|
||||
struct ccid;
|
||||
|
||||
enum dccp_role {
|
||||
DCCP_ROLE_UNDEFINED,
|
||||
DCCP_ROLE_LISTEN,
|
||||
DCCP_ROLE_CLIENT,
|
||||
DCCP_ROLE_SERVER,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dccp_sock - DCCP socket state
|
||||
*
|
||||
* @dccps_swl - sequence number window low
|
||||
* @dccps_swh - sequence number window high
|
||||
* @dccps_awl - acknowledgement number window low
|
||||
* @dccps_awh - acknowledgement number window high
|
||||
* @dccps_iss - initial sequence number sent
|
||||
* @dccps_isr - initial sequence number received
|
||||
* @dccps_osr - first OPEN sequence number received
|
||||
* @dccps_gss - greatest sequence number sent
|
||||
* @dccps_gsr - greatest valid sequence number received
|
||||
* @dccps_gar - greatest valid ack number received on a non-Sync; initialized to %dccps_iss
|
||||
* @dccps_timestamp_time - time of latest TIMESTAMP option
|
||||
* @dccps_timestamp_echo - latest timestamp received on a TIMESTAMP option
|
||||
* @dccps_ext_header_len - network protocol overhead (IP/IPv6 options)
|
||||
* @dccps_pmtu_cookie - Last pmtu seen by socket
|
||||
* @dccps_packet_size - Set thru setsockopt
|
||||
* @dccps_role - Role of this sock, one of %dccp_role
|
||||
* @dccps_ndp_count - number of Non Data Packets since last data packet
|
||||
* @dccps_hc_rx_ackpkts - receiver half connection acked packets
|
||||
*/
|
||||
struct dccp_sock {
|
||||
/* inet_connection_sock has to be the first member of dccp_sock */
|
||||
struct inet_connection_sock dccps_inet_connection;
|
||||
__u64 dccps_swl;
|
||||
__u64 dccps_swh;
|
||||
__u64 dccps_awl;
|
||||
__u64 dccps_awh;
|
||||
__u64 dccps_iss;
|
||||
__u64 dccps_isr;
|
||||
__u64 dccps_osr;
|
||||
__u64 dccps_gss;
|
||||
__u64 dccps_gsr;
|
||||
__u64 dccps_gar;
|
||||
unsigned long dccps_service;
|
||||
struct timeval dccps_timestamp_time;
|
||||
__u32 dccps_timestamp_echo;
|
||||
__u32 dccps_packet_size;
|
||||
unsigned long dccps_ndp_count;
|
||||
__u16 dccps_ext_header_len;
|
||||
__u32 dccps_pmtu_cookie;
|
||||
__u32 dccps_mss_cache;
|
||||
struct dccp_options dccps_options;
|
||||
struct dccp_ackpkts *dccps_hc_rx_ackpkts;
|
||||
void *dccps_hc_rx_ccid_private;
|
||||
void *dccps_hc_tx_ccid_private;
|
||||
struct ccid *dccps_hc_rx_ccid;
|
||||
struct ccid *dccps_hc_tx_ccid;
|
||||
struct dccp_options_received dccps_options_received;
|
||||
enum dccp_role dccps_role:2;
|
||||
};
|
||||
|
||||
static inline struct dccp_sock *dccp_sk(const struct sock *sk)
|
||||
{
|
||||
return (struct dccp_sock *)sk;
|
||||
}
|
||||
|
||||
static inline const char *dccp_role(const struct sock *sk)
|
||||
{
|
||||
switch (dccp_sk(sk)->dccps_role) {
|
||||
case DCCP_ROLE_UNDEFINED: return "undefined";
|
||||
case DCCP_ROLE_LISTEN: return "listen";
|
||||
case DCCP_ROLE_SERVER: return "server";
|
||||
case DCCP_ROLE_CLIENT: return "client";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _LINUX_DCCP_H */
|
|
@ -250,6 +250,12 @@ struct ethtool_stats {
|
|||
u64 data[0];
|
||||
};
|
||||
|
||||
struct ethtool_perm_addr {
|
||||
u32 cmd; /* ETHTOOL_GPERMADDR */
|
||||
u32 size;
|
||||
u8 data[0];
|
||||
};
|
||||
|
||||
struct net_device;
|
||||
|
||||
/* Some generic methods drivers may use in their ethtool_ops */
|
||||
|
@ -261,6 +267,8 @@ u32 ethtool_op_get_sg(struct net_device *dev);
|
|||
int ethtool_op_set_sg(struct net_device *dev, u32 data);
|
||||
u32 ethtool_op_get_tso(struct net_device *dev);
|
||||
int ethtool_op_set_tso(struct net_device *dev, u32 data);
|
||||
int ethtool_op_get_perm_addr(struct net_device *dev,
|
||||
struct ethtool_perm_addr *addr, u8 *data);
|
||||
|
||||
/**
|
||||
* ðtool_ops - Alter and report network device settings
|
||||
|
@ -294,7 +302,8 @@ int ethtool_op_set_tso(struct net_device *dev, u32 data);
|
|||
* get_strings: Return a set of strings that describe the requested objects
|
||||
* phys_id: Identify the device
|
||||
* get_stats: Return statistics about the device
|
||||
*
|
||||
* get_perm_addr: Gets the permanent hardware address
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* get_settings:
|
||||
|
@ -352,6 +361,7 @@ struct ethtool_ops {
|
|||
int (*phys_id)(struct net_device *, u32);
|
||||
int (*get_stats_count)(struct net_device *);
|
||||
void (*get_ethtool_stats)(struct net_device *, struct ethtool_stats *, u64 *);
|
||||
int (*get_perm_addr)(struct net_device *, struct ethtool_perm_addr *, u8 *);
|
||||
int (*begin)(struct net_device *);
|
||||
void (*complete)(struct net_device *);
|
||||
};
|
||||
|
@ -389,6 +399,7 @@ struct ethtool_ops {
|
|||
#define ETHTOOL_GSTATS 0x0000001d /* get NIC-specific statistics */
|
||||
#define ETHTOOL_GTSO 0x0000001e /* Get TSO enable (ethtool_value) */
|
||||
#define ETHTOOL_STSO 0x0000001f /* Set TSO enable (ethtool_value) */
|
||||
#define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */
|
||||
|
||||
/* compatibility with older code */
|
||||
#define SPARC_ETH_GSET ETHTOOL_GSET
|
||||
|
|
|
@ -26,8 +26,12 @@
|
|||
#include <linux/if_hippi.h>
|
||||
|
||||
#ifdef __KERNEL__
|
||||
extern unsigned short hippi_type_trans(struct sk_buff *skb,
|
||||
struct net_device *dev);
|
||||
|
||||
struct hippi_cb {
|
||||
__u32 ifield;
|
||||
};
|
||||
|
||||
extern __be16 hippi_type_trans(struct sk_buff *skb, struct net_device *dev);
|
||||
|
||||
extern struct net_device *alloc_hippi_dev(int sizeof_priv);
|
||||
#endif
|
||||
|
|
|
@ -110,6 +110,8 @@ static inline struct ethhdr *eth_hdr(const struct sk_buff *skb)
|
|||
{
|
||||
return (struct ethhdr *)skb->mac.raw;
|
||||
}
|
||||
|
||||
extern struct ctl_table ether_table[];
|
||||
#endif
|
||||
|
||||
#endif /* _LINUX_IF_ETHER_H */
|
||||
|
|
|
@ -44,7 +44,7 @@ struct fcllc {
|
|||
__u8 ssap; /* source SAP */
|
||||
__u8 llc; /* LLC control field */
|
||||
__u8 protid[3]; /* protocol id */
|
||||
__u16 ethertype; /* ether type field */
|
||||
__be16 ethertype; /* ether type field */
|
||||
};
|
||||
|
||||
#endif /* _LINUX_IF_FC_H */
|
||||
|
|
|
@ -85,7 +85,7 @@ struct fddi_snap_hdr
|
|||
__u8 ssap; /* always 0xAA */
|
||||
__u8 ctrl; /* always 0x03 */
|
||||
__u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */
|
||||
__u16 ethertype; /* packet type ID field */
|
||||
__be16 ethertype; /* packet type ID field */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* Define FDDI LLC frame header */
|
||||
|
|
|
@ -191,10 +191,12 @@ struct frad_local
|
|||
int buffer; /* current buffer for S508 firmware */
|
||||
};
|
||||
|
||||
extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *));
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* CONFIG_DLCI || CONFIG_DLCI_MODULE */
|
||||
|
||||
#ifdef __KERNEL__
|
||||
extern void dlci_ioctl_set(int (*hook)(unsigned int, void __user *));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -102,9 +102,9 @@ struct hippi_fp_hdr
|
|||
#error "Please fix <asm/byteorder.h>"
|
||||
#endif
|
||||
#else
|
||||
__u32 fixed;
|
||||
__be32 fixed;
|
||||
#endif
|
||||
__u32 d2_size;
|
||||
__be32 d2_size;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct hippi_le_hdr
|
||||
|
@ -144,7 +144,7 @@ struct hippi_snap_hdr
|
|||
__u8 ssap; /* always 0xAA */
|
||||
__u8 ctrl; /* always 0x03 */
|
||||
__u8 oui[HIPPI_OUI_LEN]; /* organizational universal id (zero)*/
|
||||
__u16 ethertype; /* packet type ID field */
|
||||
__be16 ethertype; /* packet type ID field */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct hippi_hdr
|
||||
|
|
|
@ -43,12 +43,16 @@ struct trh_hdr {
|
|||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/config.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
static inline struct trh_hdr *tr_hdr(const struct sk_buff *skb)
|
||||
{
|
||||
return (struct trh_hdr *)skb->mac.raw;
|
||||
}
|
||||
#ifdef CONFIG_SYSCTL
|
||||
extern struct ctl_table tr_table[];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* This is an Token-Ring LLC structure */
|
||||
|
|
|
@ -155,7 +155,6 @@ static inline int __vlan_hwaccel_rx(struct sk_buff *skb,
|
|||
{
|
||||
struct net_device_stats *stats;
|
||||
|
||||
skb->real_dev = skb->dev;
|
||||
skb->dev = grp->vlan_devices[vlan_tag & VLAN_VID_MASK];
|
||||
if (skb->dev == NULL) {
|
||||
dev_kfree_skb_any(skb);
|
||||
|
|
|
@ -129,6 +129,9 @@ struct igmpv3_query {
|
|||
#include <linux/skbuff.h>
|
||||
#include <linux/in.h>
|
||||
|
||||
extern int sysctl_igmp_max_memberships;
|
||||
extern int sysctl_igmp_max_msf;
|
||||
|
||||
struct ip_sf_socklist
|
||||
{
|
||||
unsigned int sl_max;
|
||||
|
|
|
@ -32,6 +32,7 @@ enum {
|
|||
IPPROTO_PUP = 12, /* PUP protocol */
|
||||
IPPROTO_UDP = 17, /* User Datagram Protocol */
|
||||
IPPROTO_IDP = 22, /* XNS IDP protocol */
|
||||
IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
|
||||
IPPROTO_RSVP = 46, /* RSVP protocol */
|
||||
IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
|
||||
|
||||
|
|
138
include/linux/inet_diag.h
Normal file
138
include/linux/inet_diag.h
Normal file
|
@ -0,0 +1,138 @@
|
|||
#ifndef _INET_DIAG_H_
|
||||
#define _INET_DIAG_H_ 1
|
||||
|
||||
/* Just some random number */
|
||||
#define TCPDIAG_GETSOCK 18
|
||||
#define DCCPDIAG_GETSOCK 19
|
||||
|
||||
#define INET_DIAG_GETSOCK_MAX 24
|
||||
|
||||
/* Socket identity */
|
||||
struct inet_diag_sockid {
|
||||
__u16 idiag_sport;
|
||||
__u16 idiag_dport;
|
||||
__u32 idiag_src[4];
|
||||
__u32 idiag_dst[4];
|
||||
__u32 idiag_if;
|
||||
__u32 idiag_cookie[2];
|
||||
#define INET_DIAG_NOCOOKIE (~0U)
|
||||
};
|
||||
|
||||
/* Request structure */
|
||||
|
||||
struct inet_diag_req {
|
||||
__u8 idiag_family; /* Family of addresses. */
|
||||
__u8 idiag_src_len;
|
||||
__u8 idiag_dst_len;
|
||||
__u8 idiag_ext; /* Query extended information */
|
||||
|
||||
struct inet_diag_sockid id;
|
||||
|
||||
__u32 idiag_states; /* States to dump */
|
||||
__u32 idiag_dbs; /* Tables to dump (NI) */
|
||||
};
|
||||
|
||||
enum {
|
||||
INET_DIAG_REQ_NONE,
|
||||
INET_DIAG_REQ_BYTECODE,
|
||||
};
|
||||
|
||||
#define INET_DIAG_REQ_MAX INET_DIAG_REQ_BYTECODE
|
||||
|
||||
/* Bytecode is sequence of 4 byte commands followed by variable arguments.
|
||||
* All the commands identified by "code" are conditional jumps forward:
|
||||
* to offset cc+"yes" or to offset cc+"no". "yes" is supposed to be
|
||||
* length of the command and its arguments.
|
||||
*/
|
||||
|
||||
struct inet_diag_bc_op {
|
||||
unsigned char code;
|
||||
unsigned char yes;
|
||||
unsigned short no;
|
||||
};
|
||||
|
||||
enum {
|
||||
INET_DIAG_BC_NOP,
|
||||
INET_DIAG_BC_JMP,
|
||||
INET_DIAG_BC_S_GE,
|
||||
INET_DIAG_BC_S_LE,
|
||||
INET_DIAG_BC_D_GE,
|
||||
INET_DIAG_BC_D_LE,
|
||||
INET_DIAG_BC_AUTO,
|
||||
INET_DIAG_BC_S_COND,
|
||||
INET_DIAG_BC_D_COND,
|
||||
};
|
||||
|
||||
struct inet_diag_hostcond {
|
||||
__u8 family;
|
||||
__u8 prefix_len;
|
||||
int port;
|
||||
__u32 addr[0];
|
||||
};
|
||||
|
||||
/* Base info structure. It contains socket identity (addrs/ports/cookie)
|
||||
* and, alas, the information shown by netstat. */
|
||||
struct inet_diag_msg {
|
||||
__u8 idiag_family;
|
||||
__u8 idiag_state;
|
||||
__u8 idiag_timer;
|
||||
__u8 idiag_retrans;
|
||||
|
||||
struct inet_diag_sockid id;
|
||||
|
||||
__u32 idiag_expires;
|
||||
__u32 idiag_rqueue;
|
||||
__u32 idiag_wqueue;
|
||||
__u32 idiag_uid;
|
||||
__u32 idiag_inode;
|
||||
};
|
||||
|
||||
/* Extensions */
|
||||
|
||||
enum {
|
||||
INET_DIAG_NONE,
|
||||
INET_DIAG_MEMINFO,
|
||||
INET_DIAG_INFO,
|
||||
INET_DIAG_VEGASINFO,
|
||||
INET_DIAG_CONG,
|
||||
};
|
||||
|
||||
#define INET_DIAG_MAX INET_DIAG_CONG
|
||||
|
||||
|
||||
/* INET_DIAG_MEM */
|
||||
|
||||
struct inet_diag_meminfo {
|
||||
__u32 idiag_rmem;
|
||||
__u32 idiag_wmem;
|
||||
__u32 idiag_fmem;
|
||||
__u32 idiag_tmem;
|
||||
};
|
||||
|
||||
/* INET_DIAG_VEGASINFO */
|
||||
|
||||
struct tcpvegas_info {
|
||||
__u32 tcpv_enabled;
|
||||
__u32 tcpv_rttcnt;
|
||||
__u32 tcpv_rtt;
|
||||
__u32 tcpv_minrtt;
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
struct sock;
|
||||
struct inet_hashinfo;
|
||||
|
||||
struct inet_diag_handler {
|
||||
struct inet_hashinfo *idiag_hashinfo;
|
||||
void (*idiag_get_info)(struct sock *sk,
|
||||
struct inet_diag_msg *r,
|
||||
void *info);
|
||||
__u16 idiag_info_size;
|
||||
__u16 idiag_type;
|
||||
};
|
||||
|
||||
extern int inet_diag_register(const struct inet_diag_handler *handler);
|
||||
extern void inet_diag_unregister(const struct inet_diag_handler *handler);
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _INET_DIAG_H_ */
|
|
@ -196,6 +196,8 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,
|
|||
#endif
|
||||
#endif
|
||||
|
||||
extern int inet_sk_rebuild_header(struct sock *sk);
|
||||
|
||||
struct iphdr {
|
||||
#if defined(__LITTLE_ENDIAN_BITFIELD)
|
||||
__u8 ihl:4,
|
||||
|
|
|
@ -193,6 +193,11 @@ struct inet6_skb_parm {
|
|||
|
||||
#define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
|
||||
|
||||
static inline int inet6_iif(const struct sk_buff *skb)
|
||||
{
|
||||
return IP6CB(skb)->iif;
|
||||
}
|
||||
|
||||
struct tcp6_request_sock {
|
||||
struct tcp_request_sock req;
|
||||
struct in6_addr loc_addr;
|
||||
|
@ -308,6 +313,36 @@ static inline void inet_sk_copy_descendant(struct sock *sk_to,
|
|||
|
||||
#define __ipv6_only_sock(sk) (inet6_sk(sk)->ipv6only)
|
||||
#define ipv6_only_sock(sk) ((sk)->sk_family == PF_INET6 && __ipv6_only_sock(sk))
|
||||
|
||||
#include <linux/tcp.h>
|
||||
|
||||
struct tcp6_timewait_sock {
|
||||
struct tcp_timewait_sock tw_v6_sk;
|
||||
struct in6_addr tw_v6_daddr;
|
||||
struct in6_addr tw_v6_rcv_saddr;
|
||||
};
|
||||
|
||||
static inline struct tcp6_timewait_sock *tcp6_twsk(const struct sock *sk)
|
||||
{
|
||||
return (struct tcp6_timewait_sock *)sk;
|
||||
}
|
||||
|
||||
static inline struct in6_addr *__tcp_v6_rcv_saddr(const struct sock *sk)
|
||||
{
|
||||
return likely(sk->sk_state != TCP_TIME_WAIT) ?
|
||||
&inet6_sk(sk)->rcv_saddr : &tcp6_twsk(sk)->tw_v6_rcv_saddr;
|
||||
}
|
||||
|
||||
static inline struct in6_addr *tcp_v6_rcv_saddr(const struct sock *sk)
|
||||
{
|
||||
return sk->sk_family == AF_INET6 ? __tcp_v6_rcv_saddr(sk) : NULL;
|
||||
}
|
||||
|
||||
static inline int inet_v6_ipv6only(const struct sock *sk)
|
||||
{
|
||||
return likely(sk->sk_state != TCP_TIME_WAIT) ?
|
||||
ipv6_only_sock(sk) : inet_twsk(sk)->tw_ipv6only;
|
||||
}
|
||||
#else
|
||||
#define __ipv6_only_sock(sk) 0
|
||||
#define ipv6_only_sock(sk) 0
|
||||
|
@ -322,8 +357,19 @@ static inline struct raw6_sock *raw6_sk(const struct sock *sk)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
#define __tcp_v6_rcv_saddr(__sk) NULL
|
||||
#define tcp_v6_rcv_saddr(__sk) NULL
|
||||
#define tcp_twsk_ipv6only(__sk) 0
|
||||
#define inet_v6_ipv6only(__sk) 0
|
||||
#endif /* defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) */
|
||||
|
||||
#endif
|
||||
#define INET6_MATCH(__sk, __saddr, __daddr, __ports, __dif) \
|
||||
(((*((__u32 *)&(inet_sk(__sk)->dport))) == (__ports)) && \
|
||||
((__sk)->sk_family == AF_INET6) && \
|
||||
ipv6_addr_equal(&inet6_sk(__sk)->daddr, (__saddr)) && \
|
||||
ipv6_addr_equal(&inet6_sk(__sk)->rcv_saddr, (__daddr)) && \
|
||||
(!((__sk)->sk_bound_dev_if) || ((__sk)->sk_bound_dev_if == (__dif))))
|
||||
|
||||
#endif
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _IPV6_H */
|
||||
|
|
|
@ -418,6 +418,20 @@ static inline void list_splice_init(struct list_head *list,
|
|||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe_continue - iterate over list of given type
|
||||
* continuing after existing point safe against removal of list entry
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_safe_continue(pos, n, head, member) \
|
||||
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
/**
|
||||
* list_for_each_rcu - iterate over an rcu-protected list
|
||||
* @pos: the &struct list_head to use as a loop counter.
|
||||
|
@ -620,6 +634,57 @@ static inline void hlist_add_after(struct hlist_node *n,
|
|||
next->next->pprev = &next->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_add_before_rcu - adds the specified element to the specified hlist
|
||||
* before the specified node while permitting racing traversals.
|
||||
* @n: the new element to add to the hash list.
|
||||
* @next: the existing element to add the new element before.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as hlist_add_head_rcu()
|
||||
* or hlist_del_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* hlist_for_each_rcu(), used to prevent memory-consistency
|
||||
* problems on Alpha CPUs.
|
||||
*/
|
||||
static inline void hlist_add_before_rcu(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
n->pprev = next->pprev;
|
||||
n->next = next;
|
||||
smp_wmb();
|
||||
next->pprev = &n->next;
|
||||
*(n->pprev) = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* hlist_add_after_rcu - adds the specified element to the specified hlist
|
||||
* after the specified node while permitting racing traversals.
|
||||
* @prev: the existing element to add the new element after.
|
||||
* @n: the new element to add to the hash list.
|
||||
*
|
||||
* The caller must take whatever precautions are necessary
|
||||
* (such as holding appropriate locks) to avoid racing
|
||||
* with another list-mutation primitive, such as hlist_add_head_rcu()
|
||||
* or hlist_del_rcu(), running on this same list.
|
||||
* However, it is perfectly legal to run concurrently with
|
||||
* the _rcu list-traversal primitives, such as
|
||||
* hlist_for_each_rcu(), used to prevent memory-consistency
|
||||
* problems on Alpha CPUs.
|
||||
*/
|
||||
static inline void hlist_add_after_rcu(struct hlist_node *prev,
|
||||
struct hlist_node *n)
|
||||
{
|
||||
n->next = prev->next;
|
||||
n->pprev = &prev->next;
|
||||
smp_wmb();
|
||||
prev->next = n;
|
||||
if (n->next)
|
||||
n->next->pprev = &n->next;
|
||||
}
|
||||
|
||||
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
||||
|
||||
#define hlist_for_each(pos, head) \
|
||||
|
|
|
@ -84,6 +84,7 @@ enum sock_type {
|
|||
SOCK_RAW = 3,
|
||||
SOCK_RDM = 4,
|
||||
SOCK_SEQPACKET = 5,
|
||||
SOCK_DCCP = 6,
|
||||
SOCK_PACKET = 10,
|
||||
};
|
||||
|
||||
|
@ -282,5 +283,15 @@ static struct proto_ops name##_ops = { \
|
|||
#define MODULE_ALIAS_NETPROTO(proto) \
|
||||
MODULE_ALIAS("net-pf-" __stringify(proto))
|
||||
|
||||
#define MODULE_ALIAS_NET_PF_PROTO(pf, proto) \
|
||||
MODULE_ALIAS("net-pf-" __stringify(pf) "-proto-" __stringify(proto))
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
#include <linux/sysctl.h>
|
||||
extern ctl_table net_table[];
|
||||
extern int net_msg_cost;
|
||||
extern int net_msg_burst;
|
||||
#endif
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _LINUX_NET_H */
|
||||
|
|
|
@ -244,6 +244,7 @@ struct netdev_boot_setup {
|
|||
};
|
||||
#define NETDEV_BOOT_SETUP_MAX 8
|
||||
|
||||
extern int __init netdev_boot_setup(char *str);
|
||||
|
||||
/*
|
||||
* The DEVICE structure.
|
||||
|
@ -336,6 +337,7 @@ struct net_device
|
|||
/* Interface address info. */
|
||||
unsigned char broadcast[MAX_ADDR_LEN]; /* hw bcast add */
|
||||
unsigned char dev_addr[MAX_ADDR_LEN]; /* hw address */
|
||||
unsigned char perm_addr[MAX_ADDR_LEN]; /* permanent hw address */
|
||||
unsigned char addr_len; /* hardware address length */
|
||||
unsigned short dev_id; /* for shared network cards */
|
||||
|
||||
|
@ -497,10 +499,12 @@ static inline void *netdev_priv(struct net_device *dev)
|
|||
#define SET_NETDEV_DEV(net, pdev) ((net)->class_dev.dev = (pdev))
|
||||
|
||||
struct packet_type {
|
||||
__be16 type; /* This is really htons(ether_type). */
|
||||
struct net_device *dev; /* NULL is wildcarded here */
|
||||
int (*func) (struct sk_buff *, struct net_device *,
|
||||
struct packet_type *);
|
||||
__be16 type; /* This is really htons(ether_type). */
|
||||
struct net_device *dev; /* NULL is wildcarded here */
|
||||
int (*func) (struct sk_buff *,
|
||||
struct net_device *,
|
||||
struct packet_type *,
|
||||
struct net_device *);
|
||||
void *af_packet_priv;
|
||||
struct list_head list;
|
||||
};
|
||||
|
@ -671,6 +675,7 @@ extern void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
|
|||
extern void dev_init(void);
|
||||
|
||||
extern int netdev_nit;
|
||||
extern int netdev_budget;
|
||||
|
||||
/* Called by rtnetlink.c:rtnl_unlock() */
|
||||
extern void netdev_run_todo(void);
|
||||
|
@ -697,19 +702,9 @@ static inline int netif_carrier_ok(const struct net_device *dev)
|
|||
|
||||
extern void __netdev_watchdog_up(struct net_device *dev);
|
||||
|
||||
static inline void netif_carrier_on(struct net_device *dev)
|
||||
{
|
||||
if (test_and_clear_bit(__LINK_STATE_NOCARRIER, &dev->state))
|
||||
linkwatch_fire_event(dev);
|
||||
if (netif_running(dev))
|
||||
__netdev_watchdog_up(dev);
|
||||
}
|
||||
extern void netif_carrier_on(struct net_device *dev);
|
||||
|
||||
static inline void netif_carrier_off(struct net_device *dev)
|
||||
{
|
||||
if (!test_and_set_bit(__LINK_STATE_NOCARRIER, &dev->state))
|
||||
linkwatch_fire_event(dev);
|
||||
}
|
||||
extern void netif_carrier_off(struct net_device *dev);
|
||||
|
||||
/* Hot-plugging. */
|
||||
static inline int netif_device_present(struct net_device *dev)
|
||||
|
@ -916,6 +911,14 @@ extern int skb_checksum_help(struct sk_buff *skb, int inward);
|
|||
extern void net_enable_timestamp(void);
|
||||
extern void net_disable_timestamp(void);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
extern void *dev_seq_start(struct seq_file *seq, loff_t *pos);
|
||||
extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
|
||||
extern void dev_seq_stop(struct seq_file *seq, void *v);
|
||||
#endif
|
||||
|
||||
extern void linkwatch_run_queue(void);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* _LINUX_DEV_H */
|
||||
|
|
|
@ -21,10 +21,23 @@
|
|||
#define NF_STOP 5
|
||||
#define NF_MAX_VERDICT NF_STOP
|
||||
|
||||
/* we overload the higher bits for encoding auxiliary data such as the queue
|
||||
* number. Not nice, but better than additional function arguments. */
|
||||
#define NF_VERDICT_MASK 0x0000ffff
|
||||
#define NF_VERDICT_BITS 16
|
||||
|
||||
#define NF_VERDICT_QMASK 0xffff0000
|
||||
#define NF_VERDICT_QBITS 16
|
||||
|
||||
#define NF_QUEUE_NR(x) (((x << NF_VERDICT_QBITS) & NF_VERDICT_QMASK) | NF_QUEUE)
|
||||
|
||||
/* only for userspace compatibility */
|
||||
#ifndef __KERNEL__
|
||||
/* Generic cache responses from hook functions.
|
||||
<= 0x2000 is used for protocol-flags. */
|
||||
#define NFC_UNKNOWN 0x4000
|
||||
#define NFC_ALTERED 0x8000
|
||||
#endif
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#include <linux/config.h>
|
||||
|
@ -101,15 +114,51 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
|
|||
|
||||
extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
|
||||
|
||||
typedef void nf_logfn(unsigned int hooknum,
|
||||
/* those NF_LOG_* defines and struct nf_loginfo are legacy definitios that will
|
||||
* disappear once iptables is replaced with pkttables. Please DO NOT use them
|
||||
* for any new code! */
|
||||
#define NF_LOG_TCPSEQ 0x01 /* Log TCP sequence numbers */
|
||||
#define NF_LOG_TCPOPT 0x02 /* Log TCP options */
|
||||
#define NF_LOG_IPOPT 0x04 /* Log IP options */
|
||||
#define NF_LOG_UID 0x08 /* Log UID owning local socket */
|
||||
#define NF_LOG_MASK 0x0f
|
||||
|
||||
#define NF_LOG_TYPE_LOG 0x01
|
||||
#define NF_LOG_TYPE_ULOG 0x02
|
||||
|
||||
struct nf_loginfo {
|
||||
u_int8_t type;
|
||||
union {
|
||||
struct {
|
||||
u_int32_t copy_len;
|
||||
u_int16_t group;
|
||||
u_int16_t qthreshold;
|
||||
} ulog;
|
||||
struct {
|
||||
u_int8_t level;
|
||||
u_int8_t logflags;
|
||||
} log;
|
||||
} u;
|
||||
};
|
||||
|
||||
typedef void nf_logfn(unsigned int pf,
|
||||
unsigned int hooknum,
|
||||
const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
const struct nf_loginfo *li,
|
||||
const char *prefix);
|
||||
|
||||
struct nf_logger {
|
||||
struct module *me;
|
||||
nf_logfn *logfn;
|
||||
char *name;
|
||||
};
|
||||
|
||||
/* Function to register/unregister log function. */
|
||||
int nf_log_register(int pf, nf_logfn *logfn);
|
||||
void nf_log_unregister(int pf, nf_logfn *logfn);
|
||||
int nf_log_register(int pf, struct nf_logger *logger);
|
||||
int nf_log_unregister_pf(int pf);
|
||||
void nf_log_unregister_logger(struct nf_logger *logger);
|
||||
|
||||
/* Calls the registered backend logging function */
|
||||
void nf_log_packet(int pf,
|
||||
|
@ -117,6 +166,7 @@ void nf_log_packet(int pf,
|
|||
const struct sk_buff *skb,
|
||||
const struct net_device *in,
|
||||
const struct net_device *out,
|
||||
struct nf_loginfo *li,
|
||||
const char *fmt, ...);
|
||||
|
||||
/* Activate hook; either okfn or kfree_skb called, unless a hook
|
||||
|
@ -175,11 +225,16 @@ int nf_getsockopt(struct sock *sk, int pf, int optval, char __user *opt,
|
|||
int *len);
|
||||
|
||||
/* Packet queuing */
|
||||
typedef int (*nf_queue_outfn_t)(struct sk_buff *skb,
|
||||
struct nf_info *info, void *data);
|
||||
struct nf_queue_handler {
|
||||
int (*outfn)(struct sk_buff *skb, struct nf_info *info,
|
||||
unsigned int queuenum, void *data);
|
||||
void *data;
|
||||
char *name;
|
||||
};
|
||||
extern int nf_register_queue_handler(int pf,
|
||||
nf_queue_outfn_t outfn, void *data);
|
||||
struct nf_queue_handler *qh);
|
||||
extern int nf_unregister_queue_handler(int pf);
|
||||
extern void nf_unregister_queue_handlers(struct nf_queue_handler *qh);
|
||||
extern void nf_reinject(struct sk_buff *skb,
|
||||
struct nf_info *info,
|
||||
unsigned int verdict);
|
||||
|
@ -190,6 +245,27 @@ extern void nf_ct_attach(struct sk_buff *, struct sk_buff *);
|
|||
/* FIXME: Before cache is ever used, this must be implemented for real. */
|
||||
extern void nf_invalidate_cache(int pf);
|
||||
|
||||
/* Call this before modifying an existing packet: ensures it is
|
||||
modifiable and linear to the point you care about (writable_len).
|
||||
Returns true or false. */
|
||||
extern int skb_make_writable(struct sk_buff **pskb, unsigned int writable_len);
|
||||
|
||||
struct nf_queue_rerouter {
|
||||
void (*save)(const struct sk_buff *skb, struct nf_info *info);
|
||||
int (*reroute)(struct sk_buff **skb, const struct nf_info *info);
|
||||
int rer_size;
|
||||
};
|
||||
|
||||
#define nf_info_reroute(x) ((void *)x + sizeof(struct nf_info))
|
||||
|
||||
extern int nf_register_queue_rerouter(int pf, struct nf_queue_rerouter *rer);
|
||||
extern int nf_unregister_queue_rerouter(int pf);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
#include <linux/proc_fs.h>
|
||||
extern struct proc_dir_entry *proc_net_netfilter;
|
||||
#endif
|
||||
|
||||
#else /* !CONFIG_NETFILTER */
|
||||
#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) (okfn)(skb)
|
||||
static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
|
||||
|
|
169
include/linux/netfilter/nfnetlink.h
Normal file
169
include/linux/netfilter/nfnetlink.h
Normal file
|
@ -0,0 +1,169 @@
|
|||
#ifndef _NFNETLINK_H
|
||||
#define _NFNETLINK_H
|
||||
#include <linux/types.h>
|
||||
|
||||
#ifndef __KERNEL__
|
||||
/* nfnetlink groups: Up to 32 maximum - backwards compatibility for userspace */
|
||||
#define NF_NETLINK_CONNTRACK_NEW 0x00000001
|
||||
#define NF_NETLINK_CONNTRACK_UPDATE 0x00000002
|
||||
#define NF_NETLINK_CONNTRACK_DESTROY 0x00000004
|
||||
#define NF_NETLINK_CONNTRACK_EXP_NEW 0x00000008
|
||||
#define NF_NETLINK_CONNTRACK_EXP_UPDATE 0x00000010
|
||||
#define NF_NETLINK_CONNTRACK_EXP_DESTROY 0x00000020
|
||||
#endif
|
||||
|
||||
enum nfnetlink_groups {
|
||||
NFNLGRP_NONE,
|
||||
#define NFNLGRP_NONE NFNLGRP_NONE
|
||||
NFNLGRP_CONNTRACK_NEW,
|
||||
#define NFNLGRP_CONNTRACK_NEW NFNLGRP_CONNTRACK_NEW
|
||||
NFNLGRP_CONNTRACK_UPDATE,
|
||||
#define NFNLGRP_CONNTRACK_UPDATE NFNLGRP_CONNTRACK_UPDATE
|
||||
NFNLGRP_CONNTRACK_DESTROY,
|
||||
#define NFNLGRP_CONNTRACK_DESTROY NFNLGRP_CONNTRACK_DESTROY
|
||||
NFNLGRP_CONNTRACK_EXP_NEW,
|
||||
#define NFNLGRP_CONNTRACK_EXP_NEW NFNLGRP_CONNTRACK_EXP_NEW
|
||||
NFNLGRP_CONNTRACK_EXP_UPDATE,
|
||||
#define NFNLGRP_CONNTRACK_EXP_UPDATE NFNLGRP_CONNTRACK_EXP_UPDATE
|
||||
NFNLGRP_CONNTRACK_EXP_DESTROY,
|
||||
#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
|
||||
__NFNLGRP_MAX,
|
||||
};
|
||||
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
|
||||
|
||||
/* Generic structure for encapsulation optional netfilter information.
|
||||
* It is reminiscent of sockaddr, but with sa_family replaced
|
||||
* with attribute type.
|
||||
* ! This should someday be put somewhere generic as now rtnetlink and
|
||||
* ! nfnetlink use the same attributes methods. - J. Schulist.
|
||||
*/
|
||||
|
||||
struct nfattr
|
||||
{
|
||||
u_int16_t nfa_len;
|
||||
u_int16_t nfa_type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* FIXME: Shamelessly copy and pasted from rtnetlink.h, it's time
|
||||
* to put this in a generic file */
|
||||
|
||||
#define NFA_ALIGNTO 4
|
||||
#define NFA_ALIGN(len) (((len) + NFA_ALIGNTO - 1) & ~(NFA_ALIGNTO - 1))
|
||||
#define NFA_OK(nfa,len) ((len) > 0 && (nfa)->nfa_len >= sizeof(struct nfattr) \
|
||||
&& (nfa)->nfa_len <= (len))
|
||||
#define NFA_NEXT(nfa,attrlen) ((attrlen) -= NFA_ALIGN((nfa)->nfa_len), \
|
||||
(struct nfattr *)(((char *)(nfa)) + NFA_ALIGN((nfa)->nfa_len)))
|
||||
#define NFA_LENGTH(len) (NFA_ALIGN(sizeof(struct nfattr)) + (len))
|
||||
#define NFA_SPACE(len) NFA_ALIGN(NFA_LENGTH(len))
|
||||
#define NFA_DATA(nfa) ((void *)(((char *)(nfa)) + NFA_LENGTH(0)))
|
||||
#define NFA_PAYLOAD(nfa) ((int)((nfa)->nfa_len) - NFA_LENGTH(0))
|
||||
#define NFA_NEST(skb, type) \
|
||||
({ struct nfattr *__start = (struct nfattr *) (skb)->tail; \
|
||||
NFA_PUT(skb, type, 0, NULL); \
|
||||
__start; })
|
||||
#define NFA_NEST_END(skb, start) \
|
||||
({ (start)->nfa_len = ((skb)->tail - (unsigned char *) (start)); \
|
||||
(skb)->len; })
|
||||
#define NFA_NEST_CANCEL(skb, start) \
|
||||
({ if (start) \
|
||||
skb_trim(skb, (unsigned char *) (start) - (skb)->data); \
|
||||
-1; })
|
||||
|
||||
/* General form of address family dependent message.
|
||||
*/
|
||||
struct nfgenmsg {
|
||||
u_int8_t nfgen_family; /* AF_xxx */
|
||||
u_int8_t version; /* nfnetlink version */
|
||||
u_int16_t res_id; /* resource id */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define NFNETLINK_V0 0
|
||||
|
||||
#define NFM_NFA(n) ((struct nfattr *)(((char *)(n)) \
|
||||
+ NLMSG_ALIGN(sizeof(struct nfgenmsg))))
|
||||
#define NFM_PAYLOAD(n) NLMSG_PAYLOAD(n, sizeof(struct nfgenmsg))
|
||||
|
||||
/* netfilter netlink message types are split in two pieces:
|
||||
* 8 bit subsystem, 8bit operation.
|
||||
*/
|
||||
|
||||
#define NFNL_SUBSYS_ID(x) ((x & 0xff00) >> 8)
|
||||
#define NFNL_MSG_TYPE(x) (x & 0x00ff)
|
||||
|
||||
/* No enum here, otherwise __stringify() trick of MODULE_ALIAS_NFNL_SUBSYS()
|
||||
* won't work anymore */
|
||||
#define NFNL_SUBSYS_NONE 0
|
||||
#define NFNL_SUBSYS_CTNETLINK 1
|
||||
#define NFNL_SUBSYS_CTNETLINK_EXP 2
|
||||
#define NFNL_SUBSYS_QUEUE 3
|
||||
#define NFNL_SUBSYS_ULOG 4
|
||||
#define NFNL_SUBSYS_COUNT 5
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/capability.h>
|
||||
|
||||
struct nfnl_callback
|
||||
{
|
||||
int (*call)(struct sock *nl, struct sk_buff *skb,
|
||||
struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
|
||||
kernel_cap_t cap_required; /* capabilities required for this msg */
|
||||
u_int16_t attr_count; /* number of nfattr's */
|
||||
};
|
||||
|
||||
struct nfnetlink_subsystem
|
||||
{
|
||||
const char *name;
|
||||
__u8 subsys_id; /* nfnetlink subsystem ID */
|
||||
__u8 cb_count; /* number of callbacks */
|
||||
struct nfnl_callback *cb; /* callback for individual types */
|
||||
};
|
||||
|
||||
extern void __nfa_fill(struct sk_buff *skb, int attrtype,
|
||||
int attrlen, const void *data);
|
||||
#define NFA_PUT(skb, attrtype, attrlen, data) \
|
||||
({ if (skb_tailroom(skb) < (int)NFA_SPACE(attrlen)) goto nfattr_failure; \
|
||||
__nfa_fill(skb, attrtype, attrlen, data); })
|
||||
|
||||
extern struct semaphore nfnl_sem;
|
||||
|
||||
#define nfnl_shlock() down(&nfnl_sem)
|
||||
#define nfnl_shlock_nowait() down_trylock(&nfnl_sem)
|
||||
|
||||
#define nfnl_shunlock() do { up(&nfnl_sem); \
|
||||
if(nfnl && nfnl->sk_receive_queue.qlen) \
|
||||
nfnl->sk_data_ready(nfnl, 0); \
|
||||
} while(0)
|
||||
|
||||
extern void nfnl_lock(void);
|
||||
extern void nfnl_unlock(void);
|
||||
|
||||
extern int nfnetlink_subsys_register(struct nfnetlink_subsystem *n);
|
||||
extern int nfnetlink_subsys_unregister(struct nfnetlink_subsystem *n);
|
||||
|
||||
extern int nfattr_parse(struct nfattr *tb[], int maxattr,
|
||||
struct nfattr *nfa, int len);
|
||||
|
||||
#define nfattr_parse_nested(tb, max, nfa) \
|
||||
nfattr_parse((tb), (max), NFA_DATA((nfa)), NFA_PAYLOAD((nfa)))
|
||||
|
||||
#define nfattr_bad_size(tb, max, cta_min) \
|
||||
({ int __i, __res = 0; \
|
||||
for (__i=0; __i<max; __i++) \
|
||||
if (tb[__i] && NFA_PAYLOAD(tb[__i]) < cta_min[__i]){ \
|
||||
__res = 1; \
|
||||
break; \
|
||||
} \
|
||||
__res; \
|
||||
})
|
||||
|
||||
extern int nfnetlink_send(struct sk_buff *skb, u32 pid, unsigned group,
|
||||
int echo);
|
||||
extern int nfnetlink_unicast(struct sk_buff *skb, u_int32_t pid, int flags);
|
||||
|
||||
#define MODULE_ALIAS_NFNL_SUBSYS(subsys) \
|
||||
MODULE_ALIAS("nfnetlink-subsys-" __stringify(subsys))
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _NFNETLINK_H */
|
124
include/linux/netfilter/nfnetlink_conntrack.h
Normal file
124
include/linux/netfilter/nfnetlink_conntrack.h
Normal file
|
@ -0,0 +1,124 @@
|
|||
#ifndef _IPCONNTRACK_NETLINK_H
|
||||
#define _IPCONNTRACK_NETLINK_H
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
|
||||
enum cntl_msg_types {
|
||||
IPCTNL_MSG_CT_NEW,
|
||||
IPCTNL_MSG_CT_GET,
|
||||
IPCTNL_MSG_CT_DELETE,
|
||||
IPCTNL_MSG_CT_GET_CTRZERO,
|
||||
|
||||
IPCTNL_MSG_MAX
|
||||
};
|
||||
|
||||
enum ctnl_exp_msg_types {
|
||||
IPCTNL_MSG_EXP_NEW,
|
||||
IPCTNL_MSG_EXP_GET,
|
||||
IPCTNL_MSG_EXP_DELETE,
|
||||
|
||||
IPCTNL_MSG_EXP_MAX
|
||||
};
|
||||
|
||||
|
||||
enum ctattr_type {
|
||||
CTA_UNSPEC,
|
||||
CTA_TUPLE_ORIG,
|
||||
CTA_TUPLE_REPLY,
|
||||
CTA_STATUS,
|
||||
CTA_PROTOINFO,
|
||||
CTA_HELP,
|
||||
CTA_NAT,
|
||||
CTA_TIMEOUT,
|
||||
CTA_MARK,
|
||||
CTA_COUNTERS_ORIG,
|
||||
CTA_COUNTERS_REPLY,
|
||||
CTA_USE,
|
||||
CTA_ID,
|
||||
__CTA_MAX
|
||||
};
|
||||
#define CTA_MAX (__CTA_MAX - 1)
|
||||
|
||||
enum ctattr_tuple {
|
||||
CTA_TUPLE_UNSPEC,
|
||||
CTA_TUPLE_IP,
|
||||
CTA_TUPLE_PROTO,
|
||||
__CTA_TUPLE_MAX
|
||||
};
|
||||
#define CTA_TUPLE_MAX (__CTA_TUPLE_MAX - 1)
|
||||
|
||||
enum ctattr_ip {
|
||||
CTA_IP_UNSPEC,
|
||||
CTA_IP_V4_SRC,
|
||||
CTA_IP_V4_DST,
|
||||
CTA_IP_V6_SRC,
|
||||
CTA_IP_V6_DST,
|
||||
__CTA_IP_MAX
|
||||
};
|
||||
#define CTA_IP_MAX (__CTA_IP_MAX - 1)
|
||||
|
||||
enum ctattr_l4proto {
|
||||
CTA_PROTO_UNSPEC,
|
||||
CTA_PROTO_NUM,
|
||||
CTA_PROTO_SRC_PORT,
|
||||
CTA_PROTO_DST_PORT,
|
||||
CTA_PROTO_ICMP_ID,
|
||||
CTA_PROTO_ICMP_TYPE,
|
||||
CTA_PROTO_ICMP_CODE,
|
||||
__CTA_PROTO_MAX
|
||||
};
|
||||
#define CTA_PROTO_MAX (__CTA_PROTO_MAX - 1)
|
||||
|
||||
enum ctattr_protoinfo {
|
||||
CTA_PROTOINFO_UNSPEC,
|
||||
CTA_PROTOINFO_TCP_STATE,
|
||||
__CTA_PROTOINFO_MAX
|
||||
};
|
||||
#define CTA_PROTOINFO_MAX (__CTA_PROTOINFO_MAX - 1)
|
||||
|
||||
enum ctattr_counters {
|
||||
CTA_COUNTERS_UNSPEC,
|
||||
CTA_COUNTERS_PACKETS,
|
||||
CTA_COUNTERS_BYTES,
|
||||
__CTA_COUNTERS_MAX
|
||||
};
|
||||
#define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
|
||||
|
||||
enum ctattr_nat {
|
||||
CTA_NAT_UNSPEC,
|
||||
CTA_NAT_MINIP,
|
||||
CTA_NAT_MAXIP,
|
||||
CTA_NAT_PROTO,
|
||||
__CTA_NAT_MAX
|
||||
};
|
||||
#define CTA_NAT_MAX (__CTA_NAT_MAX - 1)
|
||||
|
||||
enum ctattr_protonat {
|
||||
CTA_PROTONAT_UNSPEC,
|
||||
CTA_PROTONAT_PORT_MIN,
|
||||
CTA_PROTONAT_PORT_MAX,
|
||||
__CTA_PROTONAT_MAX
|
||||
};
|
||||
#define CTA_PROTONAT_MAX (__CTA_PROTONAT_MAX - 1)
|
||||
|
||||
enum ctattr_expect {
|
||||
CTA_EXPECT_UNSPEC,
|
||||
CTA_EXPECT_MASTER,
|
||||
CTA_EXPECT_TUPLE,
|
||||
CTA_EXPECT_MASK,
|
||||
CTA_EXPECT_TIMEOUT,
|
||||
CTA_EXPECT_ID,
|
||||
CTA_EXPECT_HELP_NAME,
|
||||
__CTA_EXPECT_MAX
|
||||
};
|
||||
#define CTA_EXPECT_MAX (__CTA_EXPECT_MAX - 1)
|
||||
|
||||
enum ctattr_help {
|
||||
CTA_HELP_UNSPEC,
|
||||
CTA_HELP_NAME,
|
||||
__CTA_HELP_MAX
|
||||
};
|
||||
#define CTA_HELP_MAX (__CTA_HELP_MAX - 1)
|
||||
|
||||
#define CTA_HELP_MAXNAMESIZE 32
|
||||
|
||||
#endif /* _IPCONNTRACK_NETLINK_H */
|
88
include/linux/netfilter/nfnetlink_log.h
Normal file
88
include/linux/netfilter/nfnetlink_log.h
Normal file
|
@ -0,0 +1,88 @@
|
|||
#ifndef _NFNETLINK_LOG_H
|
||||
#define _NFNETLINK_LOG_H
|
||||
|
||||
/* This file describes the netlink messages (i.e. 'protocol packets'),
|
||||
* and not any kind of function definitions. It is shared between kernel and
|
||||
* userspace. Don't put kernel specific stuff in here */
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
|
||||
enum nfulnl_msg_types {
|
||||
NFULNL_MSG_PACKET, /* packet from kernel to userspace */
|
||||
NFULNL_MSG_CONFIG, /* connect to a particular queue */
|
||||
|
||||
NFULNL_MSG_MAX
|
||||
};
|
||||
|
||||
struct nfulnl_msg_packet_hdr {
|
||||
u_int16_t hw_protocol; /* hw protocol (network order) */
|
||||
u_int8_t hook; /* netfilter hook */
|
||||
u_int8_t _pad;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nfulnl_msg_packet_hw {
|
||||
u_int16_t hw_addrlen;
|
||||
u_int16_t _pad;
|
||||
u_int8_t hw_addr[8];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nfulnl_msg_packet_timestamp {
|
||||
aligned_u64 sec;
|
||||
aligned_u64 usec;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define NFULNL_PREFIXLEN 30 /* just like old log target */
|
||||
|
||||
enum nfulnl_attr_type {
|
||||
NFULA_UNSPEC,
|
||||
NFULA_PACKET_HDR,
|
||||
NFULA_MARK, /* u_int32_t nfmark */
|
||||
NFULA_TIMESTAMP, /* nfulnl_msg_packet_timestamp */
|
||||
NFULA_IFINDEX_INDEV, /* u_int32_t ifindex */
|
||||
NFULA_IFINDEX_OUTDEV, /* u_int32_t ifindex */
|
||||
NFULA_IFINDEX_PHYSINDEV, /* u_int32_t ifindex */
|
||||
NFULA_IFINDEX_PHYSOUTDEV, /* u_int32_t ifindex */
|
||||
NFULA_HWADDR, /* nfulnl_msg_packet_hw */
|
||||
NFULA_PAYLOAD, /* opaque data payload */
|
||||
NFULA_PREFIX, /* string prefix */
|
||||
NFULA_UID, /* user id of socket */
|
||||
|
||||
__NFULA_MAX
|
||||
};
|
||||
#define NFULA_MAX (__NFULA_MAX - 1)
|
||||
|
||||
enum nfulnl_msg_config_cmds {
|
||||
NFULNL_CFG_CMD_NONE,
|
||||
NFULNL_CFG_CMD_BIND,
|
||||
NFULNL_CFG_CMD_UNBIND,
|
||||
NFULNL_CFG_CMD_PF_BIND,
|
||||
NFULNL_CFG_CMD_PF_UNBIND,
|
||||
};
|
||||
|
||||
struct nfulnl_msg_config_cmd {
|
||||
u_int8_t command; /* nfulnl_msg_config_cmds */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nfulnl_msg_config_mode {
|
||||
u_int32_t copy_range;
|
||||
u_int8_t copy_mode;
|
||||
u_int8_t _pad;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum nfulnl_attr_config {
|
||||
NFULA_CFG_UNSPEC,
|
||||
NFULA_CFG_CMD, /* nfulnl_msg_config_cmd */
|
||||
NFULA_CFG_MODE, /* nfulnl_msg_config_mode */
|
||||
NFULA_CFG_NLBUFSIZ, /* u_int32_t buffer size */
|
||||
NFULA_CFG_TIMEOUT, /* u_int32_t in 1/100 s */
|
||||
NFULA_CFG_QTHRESH, /* u_int32_t */
|
||||
__NFULA_CFG_MAX
|
||||
};
|
||||
#define NFULA_CFG_MAX (__NFULA_CFG_MAX -1)
|
||||
|
||||
#define NFULNL_COPY_NONE 0x00
|
||||
#define NFULNL_COPY_META 0x01
|
||||
#define NFULNL_COPY_PACKET 0x02
|
||||
|
||||
#endif /* _NFNETLINK_LOG_H */
|
89
include/linux/netfilter/nfnetlink_queue.h
Normal file
89
include/linux/netfilter/nfnetlink_queue.h
Normal file
|
@ -0,0 +1,89 @@
|
|||
#ifndef _NFNETLINK_QUEUE_H
|
||||
#define _NFNETLINK_QUEUE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/netfilter/nfnetlink.h>
|
||||
|
||||
enum nfqnl_msg_types {
|
||||
NFQNL_MSG_PACKET, /* packet from kernel to userspace */
|
||||
NFQNL_MSG_VERDICT, /* verdict from userspace to kernel */
|
||||
NFQNL_MSG_CONFIG, /* connect to a particular queue */
|
||||
|
||||
NFQNL_MSG_MAX
|
||||
};
|
||||
|
||||
struct nfqnl_msg_packet_hdr {
|
||||
u_int32_t packet_id; /* unique ID of packet in queue */
|
||||
u_int16_t hw_protocol; /* hw protocol (network order) */
|
||||
u_int8_t hook; /* netfilter hook */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nfqnl_msg_packet_hw {
|
||||
u_int16_t hw_addrlen;
|
||||
u_int16_t _pad;
|
||||
u_int8_t hw_addr[8];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct nfqnl_msg_packet_timestamp {
|
||||
aligned_u64 sec;
|
||||
aligned_u64 usec;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum nfqnl_attr_type {
|
||||
NFQA_UNSPEC,
|
||||
NFQA_PACKET_HDR,
|
||||
NFQA_VERDICT_HDR, /* nfqnl_msg_verdict_hrd */
|
||||
NFQA_MARK, /* u_int32_t nfmark */
|
||||
NFQA_TIMESTAMP, /* nfqnl_msg_packet_timestamp */
|
||||
NFQA_IFINDEX_INDEV, /* u_int32_t ifindex */
|
||||
NFQA_IFINDEX_OUTDEV, /* u_int32_t ifindex */
|
||||
NFQA_IFINDEX_PHYSINDEV, /* u_int32_t ifindex */
|
||||
NFQA_IFINDEX_PHYSOUTDEV, /* u_int32_t ifindex */
|
||||
NFQA_HWADDR, /* nfqnl_msg_packet_hw */
|
||||
NFQA_PAYLOAD, /* opaque data payload */
|
||||
|
||||
__NFQA_MAX
|
||||
};
|
||||
#define NFQA_MAX (__NFQA_MAX - 1)
|
||||
|
||||
struct nfqnl_msg_verdict_hdr {
|
||||
u_int32_t verdict;
|
||||
u_int32_t id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
enum nfqnl_msg_config_cmds {
|
||||
NFQNL_CFG_CMD_NONE,
|
||||
NFQNL_CFG_CMD_BIND,
|
||||
NFQNL_CFG_CMD_UNBIND,
|
||||
NFQNL_CFG_CMD_PF_BIND,
|
||||
NFQNL_CFG_CMD_PF_UNBIND,
|
||||
};
|
||||
|
||||
struct nfqnl_msg_config_cmd {
|
||||
u_int8_t command; /* nfqnl_msg_config_cmds */
|
||||
u_int8_t _pad;
|
||||
u_int16_t pf; /* AF_xxx for PF_[UN]BIND */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
enum nfqnl_config_mode {
|
||||
NFQNL_COPY_NONE,
|
||||
NFQNL_COPY_META,
|
||||
NFQNL_COPY_PACKET,
|
||||
};
|
||||
|
||||
struct nfqnl_msg_config_params {
|
||||
u_int32_t copy_range;
|
||||
u_int8_t copy_mode; /* enum nfqnl_config_mode */
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
enum nfqnl_attr_config {
|
||||
NFQA_CFG_UNSPEC,
|
||||
NFQA_CFG_CMD, /* nfqnl_msg_config_cmd */
|
||||
NFQA_CFG_PARAMS, /* nfqnl_msg_config_params */
|
||||
__NFQA_CFG_MAX
|
||||
};
|
||||
#define NFQA_CFG_MAX (__NFQA_CFG_MAX-1)
|
||||
|
||||
#endif /* _NFNETLINK_QUEUE_H */
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#include <linux/netfilter.h>
|
||||
|
||||
/* only for userspace compatibility */
|
||||
#ifndef __KERNEL__
|
||||
/* IP Cache bits. */
|
||||
/* Src IP address. */
|
||||
#define NFC_DN_SRC 0x0001
|
||||
|
@ -18,6 +20,7 @@
|
|||
#define NFC_DN_IF_IN 0x0004
|
||||
/* Output device. */
|
||||
#define NFC_DN_IF_OUT 0x0008
|
||||
#endif /* ! __KERNEL__ */
|
||||
|
||||
/* DECnet Hooks */
|
||||
/* After promisc drops, checksum checks. */
|
||||
|
@ -53,7 +56,21 @@ struct nf_dn_rtmsg {
|
|||
|
||||
#define NFDN_RTMSG(r) ((unsigned char *)(r) + NLMSG_ALIGN(sizeof(struct nf_dn_rtmsg)))
|
||||
|
||||
#ifndef __KERNEL__
|
||||
/* backwards compatibility for userspace */
|
||||
#define DNRMG_L1_GROUP 0x01
|
||||
#define DNRMG_L2_GROUP 0x02
|
||||
#endif
|
||||
|
||||
enum {
|
||||
DNRNG_NLGRP_NONE,
|
||||
#define DNRNG_NLGRP_NONE DNRNG_NLGRP_NONE
|
||||
DNRNG_NLGRP_L1,
|
||||
#define DNRNG_NLGRP_L1 DNRNG_NLGRP_L1
|
||||
DNRNG_NLGRP_L2,
|
||||
#define DNRNG_NLGRP_L2 DNRNG_NLGRP_L2
|
||||
__DNRNG_NLGRP_MAX
|
||||
};
|
||||
#define DNRNG_NLGRP_MAX (__DNRNG_NLGRP_MAX - 1)
|
||||
|
||||
#endif /*__LINUX_DECNET_NETFILTER_H*/
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include <linux/config.h>
|
||||
#include <linux/netfilter.h>
|
||||
|
||||
/* only for userspace compatibility */
|
||||
#ifndef __KERNEL__
|
||||
/* IP Cache bits. */
|
||||
/* Src IP address. */
|
||||
#define NFC_IP_SRC 0x0001
|
||||
|
@ -35,6 +37,7 @@
|
|||
#define NFC_IP_DST_PT 0x0400
|
||||
/* Something else about the proto */
|
||||
#define NFC_IP_PROTO_UNKNOWN 0x2000
|
||||
#endif /* ! __KERNEL__ */
|
||||
|
||||
/* IP Hooks */
|
||||
/* After promisc drops, checksum checks. */
|
||||
|
@ -77,11 +80,6 @@ enum nf_ip_hook_priorities {
|
|||
#ifdef __KERNEL__
|
||||
extern int ip_route_me_harder(struct sk_buff **pskb);
|
||||
|
||||
/* Call this before modifying an existing IP packet: ensures it is
|
||||
modifiable and linear to the point you care about (writable_len).
|
||||
Returns true or false. */
|
||||
extern int skb_ip_make_writable(struct sk_buff **pskb,
|
||||
unsigned int writable_len);
|
||||
#endif /*__KERNEL__*/
|
||||
|
||||
#endif /*__LINUX_IP_NETFILTER_H*/
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue