Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
c9fb442e
Commit
c9fb442e
authored
Feb 12, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/jgarzik/irda-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
342f5580
c085b996
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
312 additions
and
179 deletions
+312
-179
include/net/irda/irda_device.h
include/net/irda/irda_device.h
+24
-3
include/net/irda/wrapper.h
include/net/irda/wrapper.h
+0
-2
net/irda/ircomm/ircomm_param.c
net/irda/ircomm/ircomm_param.c
+3
-1
net/irda/ircomm/ircomm_tty.c
net/irda/ircomm/ircomm_tty.c
+2
-1
net/irda/irlap_event.c
net/irda/irlap_event.c
+5
-5
net/irda/irsyms.c
net/irda/irsyms.c
+1
-0
net/irda/wrapper.c
net/irda/wrapper.c
+277
-167
No files found.
include/net/irda/irda_device.h
View file @
c9fb442e
...
@@ -173,13 +173,34 @@ typedef struct {
...
@@ -173,13 +173,34 @@ typedef struct {
__u8
*
head
;
/* start of buffer */
__u8
*
head
;
/* start of buffer */
__u8
*
data
;
/* start of data in buffer */
__u8
*
data
;
/* start of data in buffer */
__u8
*
tail
;
/* end of data in buffer */
int
len
;
/* length of data */
int
len
;
/*
current
length of data */
int
truesize
;
/* total size of buffer */
int
truesize
;
/* total
allocated
size of buffer */
__u16
fcs
;
__u16
fcs
;
struct
sk_buff
*
skb
;
/* ZeroCopy Rx in async_unwrap_char() */
}
iobuff_t
;
}
iobuff_t
;
/* Maximum SIR frame (skb) that we expect to receive *unwrapped*.
* Max LAP MTU (I field) is 2048 bytes max (IrLAP 1.1, chapt 6.6.5, p40).
* Max LAP header is 2 bytes (for now).
* Max CRC is 2 bytes at SIR, 4 bytes at FIR.
* Need 1 byte for skb_reserve() to align IP header for IrLAN.
* Add a few extra bytes just to be safe (buffer is power of two anyway)
* Jean II */
#define IRDA_SKB_MAX_MTU 2064
/* Maximum SIR frame that we expect to send, wrapped (i.e. with XBOFS
* and escaped characters on top of above). */
#define IRDA_SIR_MAX_FRAME 4269
/* The SIR unwrapper async_unwrap_char() will use a Rx-copy-break mechanism
* when using the optional ZeroCopy Rx, where only small frames are memcpy
* to a smaller skb to save memory. This is the thresold under which copy
* will happen (and over which it won't happen).
* Some FIR drivers may use this #define as well...
* This is the same value as various Ethernet drivers. - Jean II */
#define IRDA_RX_COPY_THRESHOLD 256
/* Function prototypes */
/* Function prototypes */
int
irda_device_init
(
void
);
int
irda_device_init
(
void
);
void
irda_device_cleanup
(
void
);
void
irda_device_cleanup
(
void
);
...
...
include/net/irda/wrapper.h
View file @
c9fb442e
...
@@ -52,8 +52,6 @@ enum {
...
@@ -52,8 +52,6 @@ enum {
/* Proto definitions */
/* Proto definitions */
int
async_wrap_skb
(
struct
sk_buff
*
skb
,
__u8
*
tx_buff
,
int
buffsize
);
int
async_wrap_skb
(
struct
sk_buff
*
skb
,
__u8
*
tx_buff
,
int
buffsize
);
void
async_bump
(
struct
net_device
*
dev
,
struct
net_device_stats
*
stats
,
__u8
*
buf
,
int
len
);
void
async_unwrap_char
(
struct
net_device
*
dev
,
struct
net_device_stats
*
stats
,
void
async_unwrap_char
(
struct
net_device
*
dev
,
struct
net_device_stats
*
stats
,
iobuff_t
*
buf
,
__u8
byte
);
iobuff_t
*
buf
,
__u8
byte
);
...
...
net/irda/ircomm/ircomm_param.c
View file @
c9fb442e
...
@@ -442,7 +442,9 @@ static int ircomm_param_dte(void *instance, irda_param_t *param, int get)
...
@@ -442,7 +442,9 @@ static int ircomm_param_dte(void *instance, irda_param_t *param, int get)
param
->
pv
.
i
=
self
->
settings
.
dte
;
param
->
pv
.
i
=
self
->
settings
.
dte
;
else
{
else
{
dte
=
(
__u8
)
param
->
pv
.
i
;
dte
=
(
__u8
)
param
->
pv
.
i
;
self
->
settings
.
dce
=
0
;
if
(
dte
&
IRCOMM_DELTA_DTR
)
if
(
dte
&
IRCOMM_DELTA_DTR
)
self
->
settings
.
dce
|=
(
IRCOMM_DELTA_DSR
|
self
->
settings
.
dce
|=
(
IRCOMM_DELTA_DSR
|
IRCOMM_DELTA_RI
|
IRCOMM_DELTA_RI
|
...
...
net/irda/ircomm/ircomm_tty.c
View file @
c9fb442e
...
@@ -490,7 +490,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
...
@@ -490,7 +490,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
if
(
line
<
0x10
)
{
if
(
line
<
0x10
)
{
self
->
service_type
=
IRCOMM_3_WIRE
|
IRCOMM_9_WIRE
;
self
->
service_type
=
IRCOMM_3_WIRE
|
IRCOMM_9_WIRE
;
self
->
settings
.
service_type
=
IRCOMM_9_WIRE
;
/* 9 wire as default */
self
->
settings
.
service_type
=
IRCOMM_9_WIRE
;
/* 9 wire as default */
self
->
settings
.
dce
=
IRCOMM_CTS
|
IRCOMM_CD
;
/* Default line settings */
/* Jan Kiszka -> add DSR/RI -> Conform to IrCOMM spec */
self
->
settings
.
dce
=
IRCOMM_CTS
|
IRCOMM_CD
|
IRCOMM_DSR
|
IRCOMM_RI
;
/* Default line settings */
IRDA_DEBUG
(
2
,
"%s(), IrCOMM device
\n
"
,
__FUNCTION__
);
IRDA_DEBUG
(
2
,
"%s(), IrCOMM device
\n
"
,
__FUNCTION__
);
}
else
{
}
else
{
IRDA_DEBUG
(
2
,
"%s(), IrLPT device
\n
"
,
__FUNCTION__
);
IRDA_DEBUG
(
2
,
"%s(), IrLPT device
\n
"
,
__FUNCTION__
);
...
...
net/irda/irlap_event.c
View file @
c9fb442e
...
@@ -1870,7 +1870,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
...
@@ -1870,7 +1870,7 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
irlap_update_nr_received
(
self
,
info
->
nr
);
irlap_update_nr_received
(
self
,
info
->
nr
);
irlap_wait_min_turn_around
(
self
,
&
self
->
qos_tx
);
irlap_wait_min_turn_around
(
self
,
&
self
->
qos_tx
);
irlap_send_rr_frame
(
self
,
CMD
_FRAME
);
irlap_send_rr_frame
(
self
,
RSP
_FRAME
);
irlap_start_wd_timer
(
self
,
self
->
wd_timeout
);
irlap_start_wd_timer
(
self
,
self
->
wd_timeout
);
}
}
...
@@ -2035,18 +2035,18 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
...
@@ -2035,18 +2035,18 @@ static int irlap_state_nrm_s(struct irlap_cb *self, IRLAP_EVENT event,
irlap_update_nr_received
(
self
,
info
->
nr
);
irlap_update_nr_received
(
self
,
info
->
nr
);
if
(
self
->
remote_busy
)
{
if
(
self
->
remote_busy
)
{
irlap_wait_min_turn_around
(
self
,
&
self
->
qos_tx
);
irlap_wait_min_turn_around
(
self
,
&
self
->
qos_tx
);
irlap_send_rr_frame
(
self
,
CMD
_FRAME
);
irlap_send_rr_frame
(
self
,
RSP
_FRAME
);
}
else
}
else
irlap_resend_rejected_frames
(
self
,
CMD
_FRAME
);
irlap_resend_rejected_frames
(
self
,
RSP
_FRAME
);
irlap_start_wd_timer
(
self
,
self
->
wd_timeout
);
irlap_start_wd_timer
(
self
,
self
->
wd_timeout
);
break
;
break
;
case
RECV_SREJ_CMD
:
case
RECV_SREJ_CMD
:
irlap_update_nr_received
(
self
,
info
->
nr
);
irlap_update_nr_received
(
self
,
info
->
nr
);
if
(
self
->
remote_busy
)
{
if
(
self
->
remote_busy
)
{
irlap_wait_min_turn_around
(
self
,
&
self
->
qos_tx
);
irlap_wait_min_turn_around
(
self
,
&
self
->
qos_tx
);
irlap_send_rr_frame
(
self
,
CMD
_FRAME
);
irlap_send_rr_frame
(
self
,
RSP
_FRAME
);
}
else
}
else
irlap_resend_rejected_frame
(
self
,
CMD
_FRAME
);
irlap_resend_rejected_frame
(
self
,
RSP
_FRAME
);
irlap_start_wd_timer
(
self
,
self
->
wd_timeout
);
irlap_start_wd_timer
(
self
,
self
->
wd_timeout
);
break
;
break
;
case
WD_TIMER_EXPIRED
:
case
WD_TIMER_EXPIRED
:
...
...
net/irda/irsyms.c
View file @
c9fb442e
...
@@ -165,6 +165,7 @@ EXPORT_SYMBOL(irda_task_delete);
...
@@ -165,6 +165,7 @@ EXPORT_SYMBOL(irda_task_delete);
EXPORT_SYMBOL
(
async_wrap_skb
);
EXPORT_SYMBOL
(
async_wrap_skb
);
EXPORT_SYMBOL
(
async_unwrap_char
);
EXPORT_SYMBOL
(
async_unwrap_char
);
EXPORT_SYMBOL
(
irda_calc_crc16
);
EXPORT_SYMBOL
(
irda_calc_crc16
);
EXPORT_SYMBOL
(
irda_crc16_table
);
EXPORT_SYMBOL
(
irda_start_timer
);
EXPORT_SYMBOL
(
irda_start_timer
);
EXPORT_SYMBOL
(
setup_dma
);
EXPORT_SYMBOL
(
setup_dma
);
EXPORT_SYMBOL
(
infrared_mode
);
EXPORT_SYMBOL
(
infrared_mode
);
...
...
net/irda/wrapper.c
View file @
c9fb442e
...
@@ -13,6 +13,7 @@
...
@@ -13,6 +13,7 @@
*
*
* Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
* Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
* All Rights Reserved.
* All Rights Reserved.
* Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
*
*
* This program is free software; you can redistribute it and/or
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* modify it under the terms of the GNU General Public License as
...
@@ -37,29 +38,41 @@
...
@@ -37,29 +38,41 @@
#include <net/irda/irlap_frame.h>
#include <net/irda/irlap_frame.h>
#include <net/irda/irda_device.h>
#include <net/irda/irda_device.h>
static
inline
int
stuff_byte
(
__u8
byte
,
__u8
*
buf
);
/************************** FRAME WRAPPING **************************/
/*
static
void
state_outside_frame
(
struct
net_device
*
dev
,
* Unwrap and unstuff SIR frames
struct
net_device_stats
*
stats
,
*
iobuff_t
*
rx_buff
,
__u8
byte
);
* Note : at FIR and MIR, HDLC framing is used and usually handled
static
void
state_begin_frame
(
struct
net_device
*
dev
,
* by the controller, so we come here only for SIR... Jean II
struct
net_device_stats
*
stats
,
*/
iobuff_t
*
rx_buff
,
__u8
byte
);
static
void
state_link_escape
(
struct
net_device
*
dev
,
/*
struct
net_device_stats
*
stats
,
* Function stuff_byte (byte, buf)
iobuff_t
*
rx_buff
,
__u8
byte
);
*
static
void
state_inside_frame
(
struct
net_device
*
dev
,
* Byte stuff one single byte and put the result in buffer pointed to by
struct
net_device_stats
*
stats
,
* buf. The buffer must at all times be able to have two bytes inserted.
iobuff_t
*
rx_buff
,
__u8
byte
);
*
* This is in a tight loop, better inline it, so need to be prior to callers.
static
void
(
*
state
[])(
struct
net_device
*
dev
,
struct
net_device_stats
*
stats
,
* (2000 bytes on P6 200MHz, non-inlined ~370us, inline ~170us) - Jean II
iobuff_t
*
rx_buff
,
__u8
byte
)
=
*/
static
inline
int
stuff_byte
(
__u8
byte
,
__u8
*
buf
)
{
{
state_outside_frame
,
switch
(
byte
)
{
state_begin_frame
,
case
BOF
:
/* FALLTHROUGH */
state_link_escape
,
case
EOF
:
/* FALLTHROUGH */
state_inside_frame
,
case
CE
:
};
/* Insert transparently coded */
buf
[
0
]
=
CE
;
/* Send link escape */
buf
[
1
]
=
byte
^
IRDA_TRANS
;
/* Complement bit 5 */
return
2
;
/* break; */
default:
/* Non-special value, no transparency required */
buf
[
0
]
=
byte
;
return
1
;
/* break; */
}
}
/*
/*
* Function async_wrap (skb, *tx_buff, buffsize)
* Function async_wrap (skb, *tx_buff, buffsize)
...
@@ -107,7 +120,7 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
...
@@ -107,7 +120,7 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
xbofs
=
163
;
xbofs
=
163
;
}
}
memset
(
tx_buff
+
n
,
XBOF
,
xbofs
);
memset
(
tx_buff
+
n
,
XBOF
,
xbofs
);
n
+=
xbofs
;
n
+=
xbofs
;
/* Start of packet character BOF */
/* Start of packet character BOF */
...
@@ -140,31 +153,45 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
...
@@ -140,31 +153,45 @@ int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
return
n
;
return
n
;
}
}
/************************* FRAME UNWRAPPING *************************/
/*
/*
*
Function stuff_byte (byte, buf)
*
Unwrap and unstuff SIR frames
*
*
* Byte stuff one single byte and put the result in buffer pointed to by
* Complete rewrite by Jean II :
* buf. The buffer must at all times be able to have two bytes inserted.
* More inline, faster, more compact, more logical. Jean II
* (16 bytes on P6 200MHz, old 5 to 7 us, new 4 to 6 us)
* (24 bytes on P6 200MHz, old 9 to 10 us, new 7 to 8 us)
* (for reference, 115200 b/s is 1 byte every 69 us)
* And reduce wrapper.o by ~900B in the process ;-)
*
* Then, we have the addition of ZeroCopy, which is optional
* (i.e. the driver must initiate it) and improve final processing.
* (2005 B frame + EOF on P6 200MHz, without 30 to 50 us, with 10 to 25 us)
*
*
* Note : at FIR and MIR, HDLC framing is used and usually handled
* by the controller, so we come here only for SIR... Jean II
*/
*/
static
inline
int
stuff_byte
(
__u8
byte
,
__u8
*
buf
)
{
/*
switch
(
byte
)
{
* We can also choose where we want to do the CRC calculation. We can
case
BOF
:
/* FALLTHROUGH */
* do it "inline", as we receive the bytes, or "postponed", when
case
EOF
:
/* FALLTHROUGH */
* receiving the End-Of-Frame.
case
CE
:
* (16 bytes on P6 200MHz, inlined 4 to 6 us, postponed 4 to 5 us)
/* Insert transparently coded */
* (24 bytes on P6 200MHz, inlined 7 to 8 us, postponed 5 to 7 us)
buf
[
0
]
=
CE
;
/* Send link escape */
* With ZeroCopy :
buf
[
1
]
=
byte
^
IRDA_TRANS
;
/* Complement bit 5 */
* (2005 B frame on P6 200MHz, inlined 10 to 25 us, postponed 140 to 180 us)
return
2
;
* Without ZeroCopy :
/* break; */
* (2005 B frame on P6 200MHz, inlined 30 to 50 us, postponed 150 to 180 us)
default:
* (Note : numbers taken with irq disabled)
/* Non-special value, no transparency required */
*
buf
[
0
]
=
byte
;
* From those numbers, it's not clear which is the best strategy, because
return
1
;
* we end up running through a lot of data one way or another (i.e. cache
/* break; */
* misses). I personally prefer to avoid the huge latency spike of the
}
* "postponed" solution, because it come just at the time when we have
}
* lot's of protocol processing to do and it will hurt our ability to
* reach low link turnaround times... Jean II
*/
//#define POSTPONE_RX_CRC
/*
/*
* Function async_bump (buf, len, stats)
* Function async_bump (buf, len, stats)
...
@@ -172,136 +199,228 @@ static inline int stuff_byte(__u8 byte, __u8 *buf)
...
@@ -172,136 +199,228 @@ static inline int stuff_byte(__u8 byte, __u8 *buf)
* Got a frame, make a copy of it, and pass it up the stack! We can try
* Got a frame, make a copy of it, and pass it up the stack! We can try
* to inline it since it's only called from state_inside_frame
* to inline it since it's only called from state_inside_frame
*/
*/
inline
void
async_bump
(
struct
net_device
*
dev
,
struct
net_device_stats
*
stats
,
static
inline
void
__u8
*
buf
,
int
len
)
async_bump
(
struct
net_device
*
dev
,
struct
net_device_stats
*
stats
,
iobuff_t
*
rx_buff
)
{
{
struct
sk_buff
*
skb
;
struct
sk_buff
*
newskb
;
struct
sk_buff
*
dataskb
;
skb
=
dev_alloc_skb
(
len
+
1
);
int
docopy
;
if
(
!
skb
)
{
/* Check if we need to copy the data to a new skb or not.
* If the driver doesn't use ZeroCopy Rx, we have to do it.
* With ZeroCopy Rx, the rx_buff already point to a valid
* skb. But, if the frame is small, it is more efficient to
* copy it to save memory (copy will be fast anyway - that's
* called Rx-copy-break). Jean II */
docopy
=
((
rx_buff
->
skb
==
NULL
)
||
(
rx_buff
->
len
<
IRDA_RX_COPY_THRESHOLD
));
/* Allocate a new skb */
newskb
=
dev_alloc_skb
(
docopy
?
rx_buff
->
len
+
1
:
rx_buff
->
truesize
);
if
(
!
newskb
)
{
stats
->
rx_dropped
++
;
stats
->
rx_dropped
++
;
/* We could deliver the current skb if doing ZeroCopy Rx,
* but this would stall the Rx path. Better drop the
* packet... Jean II */
return
;
return
;
}
}
/* Align IP header to 20 bytes */
/* Align IP header to 20 bytes (i.e. increase skb->data)
skb_reserve
(
skb
,
1
);
* Note this is only useful with IrLAN, as PPP has a variable
* header size (2 or 1 bytes) - Jean II */
skb_reserve
(
newskb
,
1
);
if
(
docopy
)
{
/* Copy data without CRC (lenght already checked) */
memcpy
(
newskb
->
data
,
rx_buff
->
data
,
rx_buff
->
len
-
2
);
/* Deliver this skb */
dataskb
=
newskb
;
}
else
{
/* We are using ZeroCopy. Deliver old skb */
dataskb
=
rx_buff
->
skb
;
/* And hook the new skb to the rx_buff */
rx_buff
->
skb
=
newskb
;
rx_buff
->
head
=
newskb
->
data
;
/* NOT newskb->head */
//printk(KERN_DEBUG "ZeroCopy : len = %d, dataskb = %p, newskb = %p\n", rx_buff->len, dataskb, newskb);
}
/* Copy data without CRC
*/
/* Set proper length on skb (without CRC)
*/
memcpy
(
skb_put
(
skb
,
len
-
2
),
buf
,
len
-
2
);
skb_put
(
dataskb
,
rx_buff
->
len
-
2
);
/* Feed it to IrLAP layer */
/* Feed it to IrLAP layer */
skb
->
dev
=
dev
;
data
skb
->
dev
=
dev
;
skb
->
mac
.
raw
=
skb
->
data
;
dataskb
->
mac
.
raw
=
data
skb
->
data
;
skb
->
protocol
=
htons
(
ETH_P_IRDA
);
data
skb
->
protocol
=
htons
(
ETH_P_IRDA
);
netif_rx
(
skb
);
netif_rx
(
data
skb
);
stats
->
rx_packets
++
;
stats
->
rx_packets
++
;
stats
->
rx_bytes
+=
len
;
stats
->
rx_bytes
+=
rx_buff
->
len
;
/* Clean up rx_buff (redundant with async_unwrap_bof() ???) */
rx_buff
->
data
=
rx_buff
->
head
;
rx_buff
->
len
=
0
;
}
}
/*
/*
* Function async_unwrap_
char (dev, rx_buff
, byte)
* Function async_unwrap_
bof(dev
, byte)
*
*
*
Parse and de-stuff frame received from the IrDA-port
*
Handle Beggining Of Frame character received within a frame
*
*
*/
*/
inline
void
async_unwrap_char
(
struct
net_device
*
dev
,
static
inline
void
struct
net_device_stats
*
stats
,
async_unwrap_bof
(
struct
net_device
*
dev
,
iobuff_t
*
rx_buff
,
__u8
byte
)
struct
net_device_stats
*
stats
,
iobuff_t
*
rx_buff
,
__u8
byte
)
{
{
(
*
state
[
rx_buff
->
state
])(
dev
,
stats
,
rx_buff
,
byte
);
switch
(
rx_buff
->
state
)
{
case
LINK_ESCAPE
:
case
INSIDE_FRAME
:
/* Not supposed to happen, the previous frame is not
* finished - Jean II */
IRDA_DEBUG
(
1
,
"%s(), Discarding incomplete frame
\n
"
,
__FUNCTION__
);
stats
->
rx_errors
++
;
stats
->
rx_missed_errors
++
;
irda_device_set_media_busy
(
dev
,
TRUE
);
break
;
case
OUTSIDE_FRAME
:
case
BEGIN_FRAME
:
default:
/* We may receive multiple BOF at the start of frame */
break
;
}
/* Now receiving frame */
rx_buff
->
state
=
BEGIN_FRAME
;
rx_buff
->
in_frame
=
TRUE
;
/* Time to initialize receive buffer */
rx_buff
->
data
=
rx_buff
->
head
;
rx_buff
->
len
=
0
;
rx_buff
->
fcs
=
INIT_FCS
;
}
}
/*
/*
* Function
state_outside_frame (dev, rx_buff
, byte)
* Function
async_unwrap_eof(dev
, byte)
*
*
*
Not receiving any frame (or just bogus data)
*
Handle End Of Frame character received within a frame
*
*
*/
*/
static
void
state_outside_frame
(
struct
net_device
*
dev
,
static
inline
void
struct
net_device_stats
*
stats
,
async_unwrap_eof
(
struct
net_device
*
dev
,
iobuff_t
*
rx_buff
,
__u8
byte
)
struct
net_device_stats
*
stats
,
iobuff_t
*
rx_buff
,
__u8
byte
)
{
{
switch
(
byte
)
{
#ifdef POSTPONE_RX_CRC
case
BOF
:
int
i
;
rx_buff
->
state
=
BEGIN_FRAME
;
#endif
rx_buff
->
in_frame
=
TRUE
;
break
;
switch
(
rx_buff
->
state
)
{
case
XBOF
:
case
OUTSIDE_FRAME
:
/*
idev->xbofs++;
*/
/*
Probably missed the BOF
*/
break
;
stats
->
rx_errors
++
;
case
EOF
:
stats
->
rx_missed_errors
++
;
irda_device_set_media_busy
(
dev
,
TRUE
);
irda_device_set_media_busy
(
dev
,
TRUE
);
break
;
break
;
case
BEGIN_FRAME
:
case
LINK_ESCAPE
:
case
INSIDE_FRAME
:
default:
default:
irda_device_set_media_busy
(
dev
,
TRUE
);
/* Note : in the case of BEGIN_FRAME and LINK_ESCAPE,
* the fcs will most likely not match and generate an
* error, as expected - Jean II */
rx_buff
->
state
=
OUTSIDE_FRAME
;
rx_buff
->
in_frame
=
FALSE
;
#ifdef POSTPONE_RX_CRC
/* If we haven't done the CRC as we receive bytes, we
* must do it now... Jean II */
for
(
i
=
0
;
i
<
rx_buff
->
len
;
i
++
)
rx_buff
->
fcs
=
irda_fcs
(
rx_buff
->
fcs
,
rx_buff
->
data
[
i
]);
#endif
/* Test FCS and signal success if the frame is good */
if
(
rx_buff
->
fcs
==
GOOD_FCS
)
{
/* Deliver frame */
async_bump
(
dev
,
stats
,
rx_buff
);
break
;
}
else
{
/* Wrong CRC, discard frame! */
irda_device_set_media_busy
(
dev
,
TRUE
);
IRDA_DEBUG
(
1
,
"%s(), crc error
\n
"
,
__FUNCTION__
);
stats
->
rx_errors
++
;
stats
->
rx_crc_errors
++
;
}
break
;
break
;
}
}
}
}
/*
/*
* Function
state_begin_frame (i
dev, byte)
* Function
async_unwrap_ce(
dev, byte)
*
*
*
Begin of frame detected
*
Handle Character Escape character received within a frame
*
*
*/
*/
static
void
state_begin_frame
(
struct
net_device
*
dev
,
static
inline
void
struct
net_device_stats
*
stats
,
async_unwrap_ce
(
struct
net_device
*
dev
,
iobuff_t
*
rx_buff
,
__u8
byte
)
struct
net_device_stats
*
stats
,
iobuff_t
*
rx_buff
,
__u8
byte
)
{
{
/* Time to initialize receive buffer */
switch
(
rx_buff
->
state
)
{
rx_buff
->
data
=
rx_buff
->
head
;
case
OUTSIDE_FRAME
:
rx_buff
->
len
=
0
;
/* Activate carrier sense */
rx_buff
->
fcs
=
INIT_FCS
;
irda_device_set_media_busy
(
dev
,
TRUE
);
switch
(
byte
)
{
case
BOF
:
/* Continue */
break
;
case
CE
:
/* Stuffed byte */
rx_buff
->
state
=
LINK_ESCAPE
;
break
;
break
;
case
EOF
:
/* Abort frame */
case
LINK_ESCAPE
:
rx_buff
->
state
=
OUTSIDE_FRAME
;
WARNING
(
"%s: state not defined
\n
"
,
__FUNCTION__
);
IRDA_DEBUG
(
1
,
"%s(), abort frame
\n
"
,
__FUNCTION__
);
stats
->
rx_errors
++
;
stats
->
rx_frame_errors
++
;
break
;
break
;
case
BEGIN_FRAME
:
case
INSIDE_FRAME
:
default:
default:
rx_buff
->
data
[
rx_buff
->
len
++
]
=
byte
;
/* Stuffed byte comming */
rx_buff
->
fcs
=
irda_fcs
(
rx_buff
->
fcs
,
byte
);
rx_buff
->
state
=
LINK_ESCAPE
;
rx_buff
->
state
=
INSIDE_FRAME
;
break
;
break
;
}
}
}
}
/*
/*
* Function
state_link_escape
(dev, byte)
* Function
async_unwrap_other
(dev, byte)
*
*
*
Found link escape character
*
Handle other characters received within a frame
*
*
*/
*/
static
void
state_link_escape
(
struct
net_device
*
dev
,
static
inline
void
struct
net_device_stats
*
stats
,
async_unwrap_other
(
struct
net_device
*
dev
,
iobuff_t
*
rx_buff
,
__u8
byte
)
struct
net_device_stats
*
stats
,
iobuff_t
*
rx_buff
,
__u8
byte
)
{
{
switch
(
byte
)
{
switch
(
rx_buff
->
state
)
{
case
BOF
:
/* New frame? */
/* This is on the critical path, case are ordered by
IRDA_DEBUG
(
1
,
"%s(), Discarding incomplete frame
\n
"
,
* probability (most frequent first) - Jean II */
__FUNCTION__
);
case
INSIDE_FRAME
:
rx_buff
->
state
=
BEGIN_FRAME
;
/* Must be the next byte of the frame */
irda_device_set_media_busy
(
dev
,
TRUE
);
if
(
rx_buff
->
len
<
rx_buff
->
truesize
)
{
break
;
rx_buff
->
data
[
rx_buff
->
len
++
]
=
byte
;
case
CE
:
#ifndef POSTPONE_RX_CRC
WARNING
(
"%s: state not defined
\n
"
,
__FUNCTION__
);
rx_buff
->
fcs
=
irda_fcs
(
rx_buff
->
fcs
,
byte
);
break
;
#endif
case
EOF
:
/* Abort frame */
}
else
{
rx_buff
->
state
=
OUTSIDE_FRAME
;
IRDA_DEBUG
(
1
,
"%s(), Rx buffer overflow, aborting
\n
"
,
__FUNCTION__
);
rx_buff
->
state
=
OUTSIDE_FRAME
;
}
break
;
break
;
default:
case
LINK_ESCAPE
:
/*
/*
* Stuffed char, complement bit 5 of byte
* Stuffed char, complement bit 5 of byte
* following CE, IrLAP p.114
* following CE, IrLAP p.114
...
@@ -309,67 +428,58 @@ static void state_link_escape(struct net_device *dev,
...
@@ -309,67 +428,58 @@ static void state_link_escape(struct net_device *dev,
byte
^=
IRDA_TRANS
;
byte
^=
IRDA_TRANS
;
if
(
rx_buff
->
len
<
rx_buff
->
truesize
)
{
if
(
rx_buff
->
len
<
rx_buff
->
truesize
)
{
rx_buff
->
data
[
rx_buff
->
len
++
]
=
byte
;
rx_buff
->
data
[
rx_buff
->
len
++
]
=
byte
;
#ifndef POSTPONE_RX_CRC
rx_buff
->
fcs
=
irda_fcs
(
rx_buff
->
fcs
,
byte
);
rx_buff
->
fcs
=
irda_fcs
(
rx_buff
->
fcs
,
byte
);
#endif
rx_buff
->
state
=
INSIDE_FRAME
;
rx_buff
->
state
=
INSIDE_FRAME
;
}
else
{
}
else
{
IRDA_DEBUG
(
1
,
"%s(),
rx buffer overflow
\n
"
,
IRDA_DEBUG
(
1
,
"%s(),
Rx buffer overflow, aborting
\n
"
,
__FUNCTION__
);
__FUNCTION__
);
rx_buff
->
state
=
OUTSIDE_FRAME
;
rx_buff
->
state
=
OUTSIDE_FRAME
;
}
}
break
;
break
;
case
OUTSIDE_FRAME
:
/* Activate carrier sense */
if
(
byte
!=
XBOF
)
irda_device_set_media_busy
(
dev
,
TRUE
);
break
;
case
BEGIN_FRAME
:
default:
rx_buff
->
data
[
rx_buff
->
len
++
]
=
byte
;
#ifndef POSTPONE_RX_CRC
rx_buff
->
fcs
=
irda_fcs
(
rx_buff
->
fcs
,
byte
);
#endif
rx_buff
->
state
=
INSIDE_FRAME
;
break
;
}
}
}
}
/*
/*
* Function
state_inside_frame (dev
, byte)
* Function
async_unwrap_char (dev, rx_buff
, byte)
*
*
*
Handle bytes received within a frame
*
Parse and de-stuff frame received from the IrDA-port
*
*
* This is the main entry point for SIR drivers.
*/
*/
static
void
state_inside_frame
(
struct
net_device
*
dev
,
void
async_unwrap_char
(
struct
net_device
*
dev
,
struct
net_device_stats
*
stats
,
struct
net_device_stats
*
stats
,
iobuff_t
*
rx_buff
,
__u8
byte
)
iobuff_t
*
rx_buff
,
__u8
byte
)
{
{
int
ret
=
0
;
switch
(
byte
)
{
case
CE
:
switch
(
byte
)
{
async_unwrap_ce
(
dev
,
stats
,
rx_buff
,
byte
);
case
BOF
:
/* New frame? */
IRDA_DEBUG
(
1
,
"%s(), Discarding incomplete frame
\n
"
,
__FUNCTION__
);
rx_buff
->
state
=
BEGIN_FRAME
;
irda_device_set_media_busy
(
dev
,
TRUE
);
break
;
break
;
case
CE
:
/* Stuffed char */
case
BOF
:
rx_buff
->
state
=
LINK_ESCAPE
;
async_unwrap_bof
(
dev
,
stats
,
rx_buff
,
byte
)
;
break
;
break
;
case
EOF
:
/* End of frame */
case
EOF
:
rx_buff
->
state
=
OUTSIDE_FRAME
;
async_unwrap_eof
(
dev
,
stats
,
rx_buff
,
byte
);
rx_buff
->
in_frame
=
FALSE
;
/* Test FCS and signal success if the frame is good */
if
(
rx_buff
->
fcs
==
GOOD_FCS
)
{
/* Deliver frame */
async_bump
(
dev
,
stats
,
rx_buff
->
data
,
rx_buff
->
len
);
ret
=
TRUE
;
break
;
}
else
{
/* Wrong CRC, discard frame! */
irda_device_set_media_busy
(
dev
,
TRUE
);
IRDA_DEBUG
(
1
,
"%s(), crc error
\n
"
,
__FUNCTION__
);
stats
->
rx_errors
++
;
stats
->
rx_crc_errors
++
;
}
break
;
break
;
default:
/* Must be the next byte of the frame */
default:
if
(
rx_buff
->
len
<
rx_buff
->
truesize
)
{
async_unwrap_other
(
dev
,
stats
,
rx_buff
,
byte
);
rx_buff
->
data
[
rx_buff
->
len
++
]
=
byte
;
rx_buff
->
fcs
=
irda_fcs
(
rx_buff
->
fcs
,
byte
);
}
else
{
IRDA_DEBUG
(
1
,
"%s(), Rx buffer overflow, aborting
\n
"
,
__FUNCTION__
);
rx_buff
->
state
=
OUTSIDE_FRAME
;
}
break
;
break
;
}
}
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment