Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
8a75e7d6
Commit
8a75e7d6
authored
May 25, 2005
by
Committed by
Jeff Garzik
May 25, 2005
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of /spare/repo/netdev-2.6 branch qeth
parents
f5a702b2
05e08a2a
Changes
14
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
914 additions
and
901 deletions
+914
-901
drivers/s390/net/Makefile
drivers/s390/net/Makefile
+2
-1
drivers/s390/net/ctcdbug.h
drivers/s390/net/ctcdbug.h
+8
-4
drivers/s390/net/ctcmain.c
drivers/s390/net/ctcmain.c
+206
-410
drivers/s390/net/ctcmain.h
drivers/s390/net/ctcmain.h
+276
-0
drivers/s390/net/ctctty.c
drivers/s390/net/ctctty.c
+2
-3
drivers/s390/net/cu3088.c
drivers/s390/net/cu3088.c
+3
-1
drivers/s390/net/cu3088.h
drivers/s390/net/cu3088.h
+3
-0
drivers/s390/net/iucv.c
drivers/s390/net/iucv.c
+5
-5
drivers/s390/net/lcs.c
drivers/s390/net/lcs.c
+17
-16
drivers/s390/net/qeth.h
drivers/s390/net/qeth.h
+28
-7
drivers/s390/net/qeth_eddp.c
drivers/s390/net/qeth_eddp.c
+20
-31
drivers/s390/net/qeth_main.c
drivers/s390/net/qeth_main.c
+213
-103
drivers/s390/net/qeth_tso.c
drivers/s390/net/qeth_tso.c
+0
-285
drivers/s390/net/qeth_tso.h
drivers/s390/net/qeth_tso.h
+131
-35
No files found.
drivers/s390/net/Makefile
View file @
8a75e7d6
...
@@ -9,6 +9,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
...
@@ -9,6 +9,7 @@ obj-$(CONFIG_NETIUCV) += netiucv.o fsm.o
obj-$(CONFIG_SMSGIUCV)
+=
smsgiucv.o
obj-$(CONFIG_SMSGIUCV)
+=
smsgiucv.o
obj-$(CONFIG_CTC)
+=
ctc.o fsm.o cu3088.o
obj-$(CONFIG_CTC)
+=
ctc.o fsm.o cu3088.o
obj-$(CONFIG_LCS)
+=
lcs.o cu3088.o
obj-$(CONFIG_LCS)
+=
lcs.o cu3088.o
qeth-y
:=
qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o qeth_tso.o
obj-$(CONFIG_CLAW)
+=
claw.o cu3088.o
qeth-y
:=
qeth_main.o qeth_mpc.o qeth_sys.o qeth_eddp.o
qeth-$(CONFIG_PROC_FS)
+=
qeth_proc.o
qeth-$(CONFIG_PROC_FS)
+=
qeth_proc.o
obj-$(CONFIG_QETH)
+=
qeth.o
obj-$(CONFIG_QETH)
+=
qeth.o
drivers/s390/net/ctcdbug.h
View file @
8a75e7d6
/*
/*
*
*
* linux/drivers/s390/net/ctcdbug.h ($Revision: 1.
4
$)
* linux/drivers/s390/net/ctcdbug.h ($Revision: 1.
5
$)
*
*
* CTC / ESCON network driver - s390 dbf exploit.
* CTC / ESCON network driver - s390 dbf exploit.
*
*
...
@@ -9,7 +9,7 @@
...
@@ -9,7 +9,7 @@
* Author(s): Original Code written by
* Author(s): Original Code written by
* Peter Tiedemann (ptiedem@de.ibm.com)
* Peter Tiedemann (ptiedem@de.ibm.com)
*
*
* $Revision: 1.
4 $ $Date: 2004/10/15 09:26:58
$
* $Revision: 1.
5 $ $Date: 2005/02/27 19:46:44
$
*
*
* This program is free software; you can redistribute it and/or modify
* 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
* it under the terms of the GNU General Public License as published by
...
@@ -25,9 +25,11 @@
...
@@ -25,9 +25,11 @@
* along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
*/
#ifndef _CTCDBUG_H_
#define _CTCDBUG_H_
#include <asm/debug.h>
#include <asm/debug.h>
#include "ctcmain.h"
/**
/**
* Debug Facility stuff
* Debug Facility stuff
*/
*/
...
@@ -41,7 +43,7 @@
...
@@ -41,7 +43,7 @@
#define CTC_DBF_DATA_LEN 128
#define CTC_DBF_DATA_LEN 128
#define CTC_DBF_DATA_INDEX 3
#define CTC_DBF_DATA_INDEX 3
#define CTC_DBF_DATA_NR_AREAS 1
#define CTC_DBF_DATA_NR_AREAS 1
#define CTC_DBF_DATA_LEVEL
2
#define CTC_DBF_DATA_LEVEL
3
#define CTC_DBF_TRACE_NAME "ctc_trace"
#define CTC_DBF_TRACE_NAME "ctc_trace"
#define CTC_DBF_TRACE_LEN 16
#define CTC_DBF_TRACE_LEN 16
...
@@ -121,3 +123,5 @@ hex_dump(unsigned char *buf, size_t len)
...
@@ -121,3 +123,5 @@ hex_dump(unsigned char *buf, size_t len)
printk
(
"
\n
"
);
printk
(
"
\n
"
);
}
}
#endif
drivers/s390/net/ctcmain.c
View file @
8a75e7d6
This diff is collapsed.
Click to expand it.
drivers/s390/net/ctcmain.h
0 → 100644
View file @
8a75e7d6
/*
* $Id: ctcmain.h,v 1.4 2005/03/24 09:04:17 mschwide Exp $
*
* CTC / ESCON network driver
*
* Copyright (C) 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation
* Author(s): Fritz Elfert (elfert@de.ibm.com, felfert@millenux.com)
Peter Tiedemann (ptiedem@de.ibm.com)
*
*
* Documentation used:
* - Principles of Operation (IBM doc#: SA22-7201-06)
* - Common IO/-Device Commands and Self Description (IBM doc#: SA22-7204-02)
* - Common IO/-Device Commands and Self Description (IBM doc#: SN22-5535)
* - ESCON Channel-to-Channel Adapter (IBM doc#: SA22-7203-00)
* - ESCON I/O Interface (IBM doc#: SA22-7202-029
*
* 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* RELEASE-TAG: CTC/ESCON network driver $Revision: 1.4 $
*
*/
#ifndef _CTCMAIN_H_
#define _CTCMAIN_H_
#include <asm/ccwdev.h>
#include <asm/ccwgroup.h>
#include "ctctty.h"
#include "fsm.h"
#include "cu3088.h"
/**
* CCW commands, used in this driver.
*/
#define CCW_CMD_WRITE 0x01
#define CCW_CMD_READ 0x02
#define CCW_CMD_SET_EXTENDED 0xc3
#define CCW_CMD_PREPARE 0xe3
#define CTC_PROTO_S390 0
#define CTC_PROTO_LINUX 1
#define CTC_PROTO_LINUX_TTY 2
#define CTC_PROTO_OS390 3
#define CTC_PROTO_MAX 3
#define CTC_BUFSIZE_LIMIT 65535
#define CTC_BUFSIZE_DEFAULT 32768
#define CTC_TIMEOUT_5SEC 5000
#define CTC_INITIAL_BLOCKLEN 2
#define READ 0
#define WRITE 1
#define CTC_ID_SIZE BUS_ID_SIZE+3
struct
ctc_profile
{
unsigned
long
maxmulti
;
unsigned
long
maxcqueue
;
unsigned
long
doios_single
;
unsigned
long
doios_multi
;
unsigned
long
txlen
;
unsigned
long
tx_time
;
struct
timespec
send_stamp
;
};
/**
* Definition of one channel
*/
struct
channel
{
/**
* Pointer to next channel in list.
*/
struct
channel
*
next
;
char
id
[
CTC_ID_SIZE
];
struct
ccw_device
*
cdev
;
/**
* Type of this channel.
* CTC/A or Escon for valid channels.
*/
enum
channel_types
type
;
/**
* Misc. flags. See CHANNEL_FLAGS_... below
*/
__u32
flags
;
/**
* The protocol of this channel
*/
__u16
protocol
;
/**
* I/O and irq related stuff
*/
struct
ccw1
*
ccw
;
struct
irb
*
irb
;
/**
* RX/TX buffer size
*/
int
max_bufsize
;
/**
* Transmit/Receive buffer.
*/
struct
sk_buff
*
trans_skb
;
/**
* Universal I/O queue.
*/
struct
sk_buff_head
io_queue
;
/**
* TX queue for collecting skb's during busy.
*/
struct
sk_buff_head
collect_queue
;
/**
* Amount of data in collect_queue.
*/
int
collect_len
;
/**
* spinlock for collect_queue and collect_len
*/
spinlock_t
collect_lock
;
/**
* Timer for detecting unresposive
* I/O operations.
*/
fsm_timer
timer
;
/**
* Retry counter for misc. operations.
*/
int
retry
;
/**
* The finite state machine of this channel
*/
fsm_instance
*
fsm
;
/**
* The corresponding net_device this channel
* belongs to.
*/
struct
net_device
*
netdev
;
struct
ctc_profile
prof
;
unsigned
char
*
trans_skb_data
;
__u16
logflags
;
};
#define CHANNEL_FLAGS_READ 0
#define CHANNEL_FLAGS_WRITE 1
#define CHANNEL_FLAGS_INUSE 2
#define CHANNEL_FLAGS_BUFSIZE_CHANGED 4
#define CHANNEL_FLAGS_FAILED 8
#define CHANNEL_FLAGS_WAITIRQ 16
#define CHANNEL_FLAGS_RWMASK 1
#define CHANNEL_DIRECTION(f) (f & CHANNEL_FLAGS_RWMASK)
#define LOG_FLAG_ILLEGALPKT 1
#define LOG_FLAG_ILLEGALSIZE 2
#define LOG_FLAG_OVERRUN 4
#define LOG_FLAG_NOMEM 8
#define CTC_LOGLEVEL_INFO 1
#define CTC_LOGLEVEL_NOTICE 2
#define CTC_LOGLEVEL_WARN 4
#define CTC_LOGLEVEL_EMERG 8
#define CTC_LOGLEVEL_ERR 16
#define CTC_LOGLEVEL_DEBUG 32
#define CTC_LOGLEVEL_CRIT 64
#define CTC_LOGLEVEL_DEFAULT \
(CTC_LOGLEVEL_INFO | CTC_LOGLEVEL_NOTICE | CTC_LOGLEVEL_WARN | CTC_LOGLEVEL_CRIT)
#define CTC_LOGLEVEL_MAX ((CTC_LOGLEVEL_CRIT<<1)-1)
#define ctc_pr_debug(fmt, arg...) \
do { if (loglevel & CTC_LOGLEVEL_DEBUG) printk(KERN_DEBUG fmt,##arg); } while (0)
#define ctc_pr_info(fmt, arg...) \
do { if (loglevel & CTC_LOGLEVEL_INFO) printk(KERN_INFO fmt,##arg); } while (0)
#define ctc_pr_notice(fmt, arg...) \
do { if (loglevel & CTC_LOGLEVEL_NOTICE) printk(KERN_NOTICE fmt,##arg); } while (0)
#define ctc_pr_warn(fmt, arg...) \
do { if (loglevel & CTC_LOGLEVEL_WARN) printk(KERN_WARNING fmt,##arg); } while (0)
#define ctc_pr_emerg(fmt, arg...) \
do { if (loglevel & CTC_LOGLEVEL_EMERG) printk(KERN_EMERG fmt,##arg); } while (0)
#define ctc_pr_err(fmt, arg...) \
do { if (loglevel & CTC_LOGLEVEL_ERR) printk(KERN_ERR fmt,##arg); } while (0)
#define ctc_pr_crit(fmt, arg...) \
do { if (loglevel & CTC_LOGLEVEL_CRIT) printk(KERN_CRIT fmt,##arg); } while (0)
struct
ctc_priv
{
struct
net_device_stats
stats
;
unsigned
long
tbusy
;
/**
* The finite state machine of this interface.
*/
fsm_instance
*
fsm
;
/**
* The protocol of this device
*/
__u16
protocol
;
/**
* Timer for restarting after I/O Errors
*/
fsm_timer
restart_timer
;
int
buffer_size
;
struct
channel
*
channel
[
2
];
};
/**
* Definition of our link level header.
*/
struct
ll_header
{
__u16
length
;
__u16
type
;
__u16
unused
;
};
#define LL_HEADER_LENGTH (sizeof(struct ll_header))
/**
* Compatibility macros for busy handling
* of network devices.
*/
static
__inline__
void
ctc_clear_busy
(
struct
net_device
*
dev
)
{
clear_bit
(
0
,
&
(((
struct
ctc_priv
*
)
dev
->
priv
)
->
tbusy
));
if
(((
struct
ctc_priv
*
)
dev
->
priv
)
->
protocol
!=
CTC_PROTO_LINUX_TTY
)
netif_wake_queue
(
dev
);
}
static
__inline__
int
ctc_test_and_set_busy
(
struct
net_device
*
dev
)
{
if
(((
struct
ctc_priv
*
)
dev
->
priv
)
->
protocol
!=
CTC_PROTO_LINUX_TTY
)
netif_stop_queue
(
dev
);
return
test_and_set_bit
(
0
,
&
((
struct
ctc_priv
*
)
dev
->
priv
)
->
tbusy
);
}
#endif
drivers/s390/net/ctctty.c
View file @
8a75e7d6
/*
/*
* $Id: ctctty.c,v 1.2
6 2004/08/04 11:06:55
mschwide Exp $
* $Id: ctctty.c,v 1.2
9 2005/04/05 08:50:44
mschwide Exp $
*
*
* CTC / ESCON network driver, tty interface.
* CTC / ESCON network driver, tty interface.
*
*
...
@@ -1056,8 +1056,7 @@ ctc_tty_close(struct tty_struct *tty, struct file *filp)
...
@@ -1056,8 +1056,7 @@ ctc_tty_close(struct tty_struct *tty, struct file *filp)
info
->
tty
=
0
;
info
->
tty
=
0
;
tty
->
closing
=
0
;
tty
->
closing
=
0
;
if
(
info
->
blocked_open
)
{
if
(
info
->
blocked_open
)
{
set_current_state
(
TASK_INTERRUPTIBLE
);
msleep_interruptible
(
500
);
schedule_timeout
(
HZ
/
2
);
wake_up_interruptible
(
&
info
->
open_wait
);
wake_up_interruptible
(
&
info
->
open_wait
);
}
}
info
->
flags
&=
~
(
CTC_ASYNC_NORMAL_ACTIVE
|
CTC_ASYNC_CLOSING
);
info
->
flags
&=
~
(
CTC_ASYNC_NORMAL_ACTIVE
|
CTC_ASYNC_CLOSING
);
...
...
drivers/s390/net/cu3088.c
View file @
8a75e7d6
/*
/*
* $Id: cu3088.c,v 1.3
4 2004/06/15 13:16:27 pavlic
Exp $
* $Id: cu3088.c,v 1.3
5 2005/03/30 19:28:52 richtera
Exp $
*
*
* CTC / LCS ccw_device driver
* CTC / LCS ccw_device driver
*
*
...
@@ -39,6 +39,7 @@ const char *cu3088_type[] = {
...
@@ -39,6 +39,7 @@ const char *cu3088_type[] = {
"FICON channel"
,
"FICON channel"
,
"P390 LCS card"
,
"P390 LCS card"
,
"OSA LCS card"
,
"OSA LCS card"
,
"CLAW channel device"
,
"unknown channel type"
,
"unknown channel type"
,
"unsupported channel type"
,
"unsupported channel type"
,
};
};
...
@@ -51,6 +52,7 @@ static struct ccw_device_id cu3088_ids[] = {
...
@@ -51,6 +52,7 @@ static struct ccw_device_id cu3088_ids[] = {
{
CCW_DEVICE
(
0x3088
,
0x1e
),
.
driver_info
=
channel_type_ficon
},
{
CCW_DEVICE
(
0x3088
,
0x1e
),
.
driver_info
=
channel_type_ficon
},
{
CCW_DEVICE
(
0x3088
,
0x01
),
.
driver_info
=
channel_type_p390
},
{
CCW_DEVICE
(
0x3088
,
0x01
),
.
driver_info
=
channel_type_p390
},
{
CCW_DEVICE
(
0x3088
,
0x60
),
.
driver_info
=
channel_type_osa2
},
{
CCW_DEVICE
(
0x3088
,
0x60
),
.
driver_info
=
channel_type_osa2
},
{
CCW_DEVICE
(
0x3088
,
0x61
),
.
driver_info
=
channel_type_claw
},
{
/* end of list */
}
{
/* end of list */
}
};
};
...
...
drivers/s390/net/cu3088.h
View file @
8a75e7d6
...
@@ -23,6 +23,9 @@ enum channel_types {
...
@@ -23,6 +23,9 @@ enum channel_types {
/* Device is a OSA2 card */
/* Device is a OSA2 card */
channel_type_osa2
,
channel_type_osa2
,
/* Device is a CLAW channel device */
channel_type_claw
,
/* Device is a channel, but we don't know
/* Device is a channel, but we don't know
* anything about it */
* anything about it */
channel_type_unknown
,
channel_type_unknown
,
...
...
drivers/s390/net/iucv.c
View file @
8a75e7d6
/*
/*
* $Id: iucv.c,v 1.4
3 2005/02/09 14:47:43
braunu Exp $
* $Id: iucv.c,v 1.4
5 2005/04/26 22:59:06
braunu Exp $
*
*
* IUCV network driver
* IUCV network driver
*
*
...
@@ -29,7 +29,7 @@
...
@@ -29,7 +29,7 @@
* along with this program; if not, write to the Free Software
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*
* RELEASE-TAG: IUCV lowlevel driver $Revision: 1.4
3
$
* RELEASE-TAG: IUCV lowlevel driver $Revision: 1.4
5
$
*
*
*/
*/
...
@@ -355,7 +355,7 @@ do { \
...
@@ -355,7 +355,7 @@ do { \
static
void
static
void
iucv_banner
(
void
)
iucv_banner
(
void
)
{
{
char
vbuf
[]
=
"$Revision: 1.4
3
$"
;
char
vbuf
[]
=
"$Revision: 1.4
5
$"
;
char
*
version
=
vbuf
;
char
*
version
=
vbuf
;
if
((
version
=
strchr
(
version
,
':'
)))
{
if
((
version
=
strchr
(
version
,
':'
)))
{
...
@@ -2553,12 +2553,12 @@ EXPORT_SYMBOL (iucv_resume);
...
@@ -2553,12 +2553,12 @@ EXPORT_SYMBOL (iucv_resume);
#endif
#endif
EXPORT_SYMBOL
(
iucv_reply_prmmsg
);
EXPORT_SYMBOL
(
iucv_reply_prmmsg
);
EXPORT_SYMBOL
(
iucv_send
);
EXPORT_SYMBOL
(
iucv_send
);
#if 0
EXPORT_SYMBOL
(
iucv_send2way
);
EXPORT_SYMBOL
(
iucv_send2way
);
EXPORT_SYMBOL
(
iucv_send2way_array
);
EXPORT_SYMBOL
(
iucv_send2way_array
);
EXPORT_SYMBOL (iucv_send_array);
EXPORT_SYMBOL
(
iucv_send2way_prmmsg
);
EXPORT_SYMBOL
(
iucv_send2way_prmmsg
);
EXPORT_SYMBOL
(
iucv_send2way_prmmsg_array
);
EXPORT_SYMBOL
(
iucv_send2way_prmmsg_array
);
#if 0
EXPORT_SYMBOL (iucv_send_array);
EXPORT_SYMBOL (iucv_send_prmmsg);
EXPORT_SYMBOL (iucv_send_prmmsg);
EXPORT_SYMBOL (iucv_setmask);
EXPORT_SYMBOL (iucv_setmask);
#endif
#endif
...
...
drivers/s390/net/lcs.c
View file @
8a75e7d6
...
@@ -11,7 +11,7 @@
...
@@ -11,7 +11,7 @@
* Frank Pavlic (pavlic@de.ibm.com) and
* Frank Pavlic (pavlic@de.ibm.com) and
* Martin Schwidefsky <schwidefsky@de.ibm.com>
* Martin Schwidefsky <schwidefsky@de.ibm.com>
*
*
* $Revision: 1.9
6 $ $Date: 2004/11/11 13:42:33
$
* $Revision: 1.9
8 $ $Date: 2005/04/18 13:41:29
$
*
*
* This program is free software; you can redistribute it and/or modify
* 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
* it under the terms of the GNU General Public License as published by
...
@@ -59,7 +59,7 @@
...
@@ -59,7 +59,7 @@
/**
/**
* initialization string for output
* initialization string for output
*/
*/
#define VERSION_LCS_C "$Revision: 1.9
6
$"
#define VERSION_LCS_C "$Revision: 1.9
8
$"
static
char
version
[]
__initdata
=
"LCS driver ("
VERSION_LCS_C
"/"
VERSION_LCS_H
")"
;
static
char
version
[]
__initdata
=
"LCS driver ("
VERSION_LCS_C
"/"
VERSION_LCS_H
")"
;
static
char
debug_buffer
[
255
];
static
char
debug_buffer
[
255
];
...
@@ -1098,14 +1098,6 @@ lcs_check_multicast_support(struct lcs_card *card)
...
@@ -1098,14 +1098,6 @@ lcs_check_multicast_support(struct lcs_card *card)
PRINT_ERR
(
"Query IPAssist failed. Assuming unsupported!
\n
"
);
PRINT_ERR
(
"Query IPAssist failed. Assuming unsupported!
\n
"
);
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
}
}
/* Print out supported assists: IPv6 */
PRINT_INFO
(
"LCS device %s %s IPv6 support
\n
"
,
card
->
dev
->
name
,
(
card
->
ip_assists_supported
&
LCS_IPASS_IPV6_SUPPORT
)
?
"with"
:
"without"
);
/* Print out supported assist: Multicast */
PRINT_INFO
(
"LCS device %s %s Multicast support
\n
"
,
card
->
dev
->
name
,
(
card
->
ip_assists_supported
&
LCS_IPASS_MULTICAST_SUPPORT
)
?
"with"
:
"without"
);
if
(
card
->
ip_assists_supported
&
LCS_IPASS_MULTICAST_SUPPORT
)
if
(
card
->
ip_assists_supported
&
LCS_IPASS_MULTICAST_SUPPORT
)
return
0
;
return
0
;
return
-
EOPNOTSUPP
;
return
-
EOPNOTSUPP
;
...
@@ -1160,7 +1152,7 @@ list_modified:
...
@@ -1160,7 +1152,7 @@ list_modified:
}
}
}
}
/* re-insert all entries from the failed_list into ipm_list */
/* re-insert all entries from the failed_list into ipm_list */
list_for_each_entry
(
ipm
,
&
failed_list
,
list
)
{
list_for_each_entry
_safe
(
ipm
,
tmp
,
&
failed_list
,
list
)
{
list_del_init
(
&
ipm
->
list
);
list_del_init
(
&
ipm
->
list
);
list_add_tail
(
&
ipm
->
list
,
&
card
->
ipm_list
);
list_add_tail
(
&
ipm
->
list
,
&
card
->
ipm_list
);
}
}
...
@@ -2198,30 +2190,39 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
...
@@ -2198,30 +2190,39 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
if
(
!
dev
)
if
(
!
dev
)
goto
out
;
goto
out
;
card
->
dev
=
dev
;
card
->
dev
=
dev
;
netdev_out:
card
->
dev
->
priv
=
card
;
card
->
dev
->
priv
=
card
;
card
->
dev
->
open
=
lcs_open_device
;
card
->
dev
->
open
=
lcs_open_device
;
card
->
dev
->
stop
=
lcs_stop_device
;
card
->
dev
->
stop
=
lcs_stop_device
;
card
->
dev
->
hard_start_xmit
=
lcs_start_xmit
;
card
->
dev
->
hard_start_xmit
=
lcs_start_xmit
;
card
->
dev
->
get_stats
=
lcs_getstats
;
card
->
dev
->
get_stats
=
lcs_getstats
;
SET_MODULE_OWNER
(
dev
);
SET_MODULE_OWNER
(
dev
);
if
(
lcs_register_netdev
(
ccwgdev
)
!=
0
)
goto
out
;
memcpy
(
card
->
dev
->
dev_addr
,
card
->
mac
,
LCS_MAC_LENGTH
);
memcpy
(
card
->
dev
->
dev_addr
,
card
->
mac
,
LCS_MAC_LENGTH
);
#ifdef CONFIG_IP_MULTICAST
#ifdef CONFIG_IP_MULTICAST
if
(
!
lcs_check_multicast_support
(
card
))
if
(
!
lcs_check_multicast_support
(
card
))
card
->
dev
->
set_multicast_list
=
lcs_set_multicast_list
;
card
->
dev
->
set_multicast_list
=
lcs_set_multicast_list
;
#endif
#endif
netif_stop_queue
(
card
->
dev
);
netdev_out:
lcs_set_allowed_threads
(
card
,
0xffffffff
);
lcs_set_allowed_threads
(
card
,
0xffffffff
);
if
(
recover_state
==
DEV_STATE_RECOVER
)
{
if
(
recover_state
==
DEV_STATE_RECOVER
)
{
lcs_set_multicast_list
(
card
->
dev
);
lcs_set_multicast_list
(
card
->
dev
);
card
->
dev
->
flags
|=
IFF_UP
;
card
->
dev
->
flags
|=
IFF_UP
;
netif_wake_queue
(
card
->
dev
);
netif_wake_queue
(
card
->
dev
);
card
->
state
=
DEV_STATE_UP
;
card
->
state
=
DEV_STATE_UP
;
}
else
}
else
{
lcs_stopcard
(
card
);
lcs_stopcard
(
card
);
}
if
(
lcs_register_netdev
(
ccwgdev
)
!=
0
)
goto
out
;
/* Print out supported assists: IPv6 */
PRINT_INFO
(
"LCS device %s %s IPv6 support
\n
"
,
card
->
dev
->
name
,
(
card
->
ip_assists_supported
&
LCS_IPASS_IPV6_SUPPORT
)
?
"with"
:
"without"
);
/* Print out supported assist: Multicast */
PRINT_INFO
(
"LCS device %s %s Multicast support
\n
"
,
card
->
dev
->
name
,
(
card
->
ip_assists_supported
&
LCS_IPASS_MULTICAST_SUPPORT
)
?
"with"
:
"without"
);
return
0
;
return
0
;
out:
out:
...
...
drivers/s390/net/qeth.h
View file @
8a75e7d6
...
@@ -24,7 +24,7 @@
...
@@ -24,7 +24,7 @@
#include "qeth_mpc.h"
#include "qeth_mpc.h"
#define VERSION_QETH_H "$Revision: 1.13
5
$"
#define VERSION_QETH_H "$Revision: 1.13
9
$"
#ifdef CONFIG_QETH_IPV6
#ifdef CONFIG_QETH_IPV6
#define QETH_VERSION_IPV6 ":IPv6"
#define QETH_VERSION_IPV6 ":IPv6"
...
@@ -288,7 +288,8 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
...
@@ -288,7 +288,8 @@ qeth_is_ipa_enabled(struct qeth_ipa_info *ipa, enum qeth_ipa_funcs func)
#define QETH_TX_TIMEOUT 100 * HZ
#define QETH_TX_TIMEOUT 100 * HZ
#define QETH_HEADER_SIZE 32
#define QETH_HEADER_SIZE 32
#define MAX_PORTNO 15
#define MAX_PORTNO 15
#define QETH_FAKE_LL_LEN ETH_HLEN
#define QETH_FAKE_LL_LEN_ETH ETH_HLEN
#define QETH_FAKE_LL_LEN_TR (sizeof(struct trh_hdr)-TR_MAXRIFLEN+sizeof(struct trllc))
#define QETH_FAKE_LL_V6_ADDR_POS 24
#define QETH_FAKE_LL_V6_ADDR_POS 24
/*IPv6 address autoconfiguration stuff*/
/*IPv6 address autoconfiguration stuff*/
...
@@ -369,6 +370,25 @@ struct qeth_hdr {
...
@@ -369,6 +370,25 @@ struct qeth_hdr {
}
hdr
;
}
hdr
;
}
__attribute__
((
packed
));
}
__attribute__
((
packed
));
/*TCP Segmentation Offload header*/
struct
qeth_hdr_ext_tso
{
__u16
hdr_tot_len
;
__u8
imb_hdr_no
;
__u8
reserved
;
__u8
hdr_type
;
__u8
hdr_version
;
__u16
hdr_len
;
__u32
payload_len
;
__u16
mss
;
__u16
dg_hdr_len
;
__u8
padding
[
16
];
}
__attribute__
((
packed
));
struct
qeth_hdr_tso
{
struct
qeth_hdr
hdr
;
/*hdr->hdr.l3.xxx*/
struct
qeth_hdr_ext_tso
ext
;
}
__attribute__
((
packed
));
/* flags for qeth_hdr.flags */
/* flags for qeth_hdr.flags */
#define QETH_HDR_PASSTHRU 0x10
#define QETH_HDR_PASSTHRU 0x10
...
@@ -866,6 +886,7 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size)
...
@@ -866,6 +886,7 @@ qeth_push_skb(struct qeth_card *card, struct sk_buff **skb, int size)
return
hdr
;
return
hdr
;
}
}
inline
static
int
inline
static
int
qeth_get_hlen
(
__u8
link_type
)
qeth_get_hlen
(
__u8
link_type
)
{
{
...
@@ -873,19 +894,19 @@ qeth_get_hlen(__u8 link_type)
...
@@ -873,19 +894,19 @@ qeth_get_hlen(__u8 link_type)
switch
(
link_type
)
{
switch
(
link_type
)
{
case
QETH_LINK_TYPE_HSTR
:
case
QETH_LINK_TYPE_HSTR
:
case
QETH_LINK_TYPE_LANE_TR
:
case
QETH_LINK_TYPE_LANE_TR
:
return
sizeof
(
struct
qeth_hdr
)
+
TR_HLEN
;
return
sizeof
(
struct
qeth_hdr
_tso
)
+
TR_HLEN
;
default:
default:
#ifdef CONFIG_QETH_VLAN
#ifdef CONFIG_QETH_VLAN
return
sizeof
(
struct
qeth_hdr
)
+
VLAN_ETH_HLEN
;
return
sizeof
(
struct
qeth_hdr
_tso
)
+
VLAN_ETH_HLEN
;
#else
#else
return
sizeof
(
struct
qeth_hdr
)
+
ETH_HLEN
;
return
sizeof
(
struct
qeth_hdr
_tso
)
+
ETH_HLEN
;
#endif
#endif
}
}
#else
/* CONFIG_QETH_IPV6 */
#else
/* CONFIG_QETH_IPV6 */
#ifdef CONFIG_QETH_VLAN
#ifdef CONFIG_QETH_VLAN
return
sizeof
(
struct
qeth_hdr
)
+
VLAN_HLEN
;
return
sizeof
(
struct
qeth_hdr
_tso
)
+
VLAN_HLEN
;
#else
#else
return
sizeof
(
struct
qeth_hdr
);
return
sizeof
(
struct
qeth_hdr
_tso
);
#endif
#endif
#endif
/* CONFIG_QETH_IPV6 */
#endif
/* CONFIG_QETH_IPV6 */
}
}
...
...
drivers/s390/net/qeth_eddp.c
View file @
8a75e7d6
/*
/*
*
*
* linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.1
1
$)
* linux/drivers/s390/net/qeth_eddp.c ($Revision: 1.1
3
$)
*
*
* Enhanced Device Driver Packing (EDDP) support for the qeth driver.
* Enhanced Device Driver Packing (EDDP) support for the qeth driver.
*
*
...
@@ -8,7 +8,7 @@
...
@@ -8,7 +8,7 @@
*
*
* Author(s): Thomas Spatzier <tspat@de.ibm.com>
* Author(s): Thomas Spatzier <tspat@de.ibm.com>
*
*
* $Revision: 1.1
1 $ $Date: 2005/03/24 09:04
:18 $
* $Revision: 1.1
3 $ $Date: 2005/05/04 20:19
:18 $
*
*
*/
*/
#include <linux/config.h>
#include <linux/config.h>
...
@@ -202,40 +202,29 @@ out:
...
@@ -202,40 +202,29 @@ out:
return
flush_cnt
;
return
flush_cnt
;
}
}
static
inline
int
qeth_get_skb_data_len
(
struct
sk_buff
*
skb
)
{
int
len
=
skb
->
len
;
int
i
;
for
(
i
=
0
;
i
<
skb_shinfo
(
skb
)
->
nr_frags
;
++
i
)
len
-=
skb_shinfo
(
skb
)
->
frags
[
i
].
size
;
return
len
;
}
static
inline
void
static
inline
void
qeth_eddp_create_segment_hdrs
(
struct
qeth_eddp_context
*
ctx
,
qeth_eddp_create_segment_hdrs
(
struct
qeth_eddp_context
*
ctx
,
struct
qeth_eddp_data
*
eddp
)
struct
qeth_eddp_data
*
eddp
,
int
data_len
)
{
{
u8
*
page
;
u8
*
page
;
int
page_remainder
;
int
page_remainder
;
int
page_offset
;
int
page_offset
;
int
hdr
_len
;
int
pkt
_len
;
struct
qeth_eddp_element
*
element
;
struct
qeth_eddp_element
*
element
;
QETH_DBF_TEXT
(
trace
,
5
,
"eddpcrsh"
);
QETH_DBF_TEXT
(
trace
,
5
,
"eddpcrsh"
);
page
=
ctx
->
pages
[
ctx
->
offset
>>
PAGE_SHIFT
];
page
=
ctx
->
pages
[
ctx
->
offset
>>
PAGE_SHIFT
];
page_offset
=
ctx
->
offset
%
PAGE_SIZE
;
page_offset
=
ctx
->
offset
%
PAGE_SIZE
;
element
=
&
ctx
->
elements
[
ctx
->
num_elements
];
element
=
&
ctx
->
elements
[
ctx
->
num_elements
];
hdr_len
=
eddp
->
nhl
+
eddp
->
thl
;
pkt_len
=
eddp
->
nhl
+
eddp
->
thl
+
data_len
;
/* FIXME: layer2 and VLAN !!! */
/* FIXME: layer2 and VLAN !!! */
if
(
eddp
->
qh
.
hdr
.
l2
.
id
==
QETH_HEADER_TYPE_LAYER2
)
if
(
eddp
->
qh
.
hdr
.
l2
.
id
==
QETH_HEADER_TYPE_LAYER2
)
hdr
_len
+=
ETH_HLEN
;
pkt
_len
+=
ETH_HLEN
;
if
(
eddp
->
mac
.
h_proto
==
__constant_htons
(
ETH_P_8021Q
))
if
(
eddp
->
mac
.
h_proto
==
__constant_htons
(
ETH_P_8021Q
))
hdr
_len
+=
VLAN_HLEN
;
pkt
_len
+=
VLAN_HLEN
;
/* does complete
header
fit in current page ? */
/* does complete
packet
fit in current page ? */
page_remainder
=
PAGE_SIZE
-
page_offset
;
page_remainder
=
PAGE_SIZE
-
page_offset
;
if
(
page_remainder
<
(
sizeof
(
struct
qeth_hdr
)
+
hdr
_len
)){
if
(
page_remainder
<
(
sizeof
(
struct
qeth_hdr
)
+
pkt
_len
)){
/* no -> go to start of next page */
/* no -> go to start of next page */
ctx
->
offset
+=
page_remainder
;
ctx
->
offset
+=
page_remainder
;
page
=
ctx
->
pages
[
ctx
->
offset
>>
PAGE_SHIFT
];
page
=
ctx
->
pages
[
ctx
->
offset
>>
PAGE_SHIFT
];
...
@@ -292,7 +281,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
...
@@ -292,7 +281,7 @@ qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
while
(
len
>
0
)
{
while
(
len
>
0
)
{
if
(
eddp
->
frag
<
0
)
{
if
(
eddp
->
frag
<
0
)
{
/* we're in skb->data */
/* we're in skb->data */
left_in_frag
=
qeth_get_skb_data_len
(
eddp
->
skb
)
left_in_frag
=
(
eddp
->
skb
->
len
-
eddp
->
skb
->
data_len
)
-
eddp
->
skb_offset
;
-
eddp
->
skb_offset
;
src
=
eddp
->
skb
->
data
+
eddp
->
skb_offset
;
src
=
eddp
->
skb
->
data
+
eddp
->
skb_offset
;
}
else
{
}
else
{
...
@@ -464,7 +453,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
...
@@ -464,7 +453,7 @@ __qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
else
else
hcsum
=
qeth_eddp_check_tcp6_hdr
(
eddp
,
data_len
);
hcsum
=
qeth_eddp_check_tcp6_hdr
(
eddp
,
data_len
);
/* fill the next segment into the context */
/* fill the next segment into the context */
qeth_eddp_create_segment_hdrs
(
ctx
,
eddp
);
qeth_eddp_create_segment_hdrs
(
ctx
,
eddp
,
data_len
);
qeth_eddp_create_segment_data_tcp
(
ctx
,
eddp
,
data_len
,
hcsum
);
qeth_eddp_create_segment_data_tcp
(
ctx
,
eddp
,
data_len
,
hcsum
);
if
(
eddp
->
skb_offset
>=
eddp
->
skb
->
len
)
if
(
eddp
->
skb_offset
>=
eddp
->
skb
->
len
)
break
;
break
;
...
...
drivers/s390/net/qeth_main.c
View file @
8a75e7d6
This diff is collapsed.
Click to expand it.
drivers/s390/net/qeth_tso.c
deleted
100644 → 0
View file @
f5a702b2
/*
* linux/drivers/s390/net/qeth_tso.c ($Revision: 1.6 $)
*
* Header file for qeth TCP Segmentation Offload support.
*
* Copyright 2004 IBM Corporation
*
* Author(s): Frank Pavlic <pavlic@de.ibm.com>
*
* $Revision: 1.6 $ $Date: 2005/03/24 09:04:18 $
*
*/
#include <linux/skbuff.h>
#include <linux/tcp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <net/ip6_checksum.h>
#include "qeth.h"
#include "qeth_mpc.h"
#include "qeth_tso.h"
/**
* skb already partially prepared
* classic qdio header in skb->data
* */
static
inline
struct
qeth_hdr_tso
*
qeth_tso_prepare_skb
(
struct
qeth_card
*
card
,
struct
sk_buff
**
skb
)
{
int
rc
=
0
;
QETH_DBF_TEXT
(
trace
,
5
,
"tsoprsk"
);
rc
=
qeth_realloc_headroom
(
card
,
skb
,
sizeof
(
struct
qeth_hdr_ext_tso
));
if
(
rc
)
return
NULL
;
return
qeth_push_skb
(
card
,
skb
,
sizeof
(
struct
qeth_hdr_ext_tso
));
}
/**
* fill header for a TSO packet
*/
static
inline
void
qeth_tso_fill_header
(
struct
qeth_card
*
card
,
struct
sk_buff
*
skb
)
{
struct
qeth_hdr_tso
*
hdr
;
struct
tcphdr
*
tcph
;
struct
iphdr
*
iph
;
QETH_DBF_TEXT
(
trace
,
5
,
"tsofhdr"
);
hdr
=
(
struct
qeth_hdr_tso
*
)
skb
->
data
;
iph
=
skb
->
nh
.
iph
;
tcph
=
skb
->
h
.
th
;
/*fix header to TSO values ...*/
hdr
->
hdr
.
hdr
.
l3
.
id
=
QETH_HEADER_TYPE_TSO
;
/*set values which are fix for the first approach ...*/
hdr
->
ext
.
hdr_tot_len
=
(
__u16
)
sizeof
(
struct
qeth_hdr_ext_tso
);
hdr
->
ext
.
imb_hdr_no
=
1
;
hdr
->
ext
.
hdr_type
=
1
;
hdr
->
ext
.
hdr_version
=
1
;
hdr
->
ext
.
hdr_len
=
28
;
/*insert non-fix values */
hdr
->
ext
.
mss
=
skb_shinfo
(
skb
)
->
tso_size
;
hdr
->
ext
.
dg_hdr_len
=
(
__u16
)(
iph
->
ihl
*
4
+
tcph
->
doff
*
4
);
hdr
->
ext
.
payload_len
=
(
__u16
)(
skb
->
len
-
hdr
->
ext
.
dg_hdr_len
-
sizeof
(
struct
qeth_hdr_tso
));
}
/**
* change some header values as requested by hardware
*/
static
inline
void
qeth_tso_set_tcpip_header
(
struct
qeth_card
*
card
,
struct
sk_buff
*
skb
)
{
struct
iphdr
*
iph
;
struct
ipv6hdr
*
ip6h
;
struct
tcphdr
*
tcph
;
iph
=
skb
->
nh
.
iph
;
ip6h
=
skb
->
nh
.
ipv6h
;
tcph
=
skb
->
h
.
th
;
tcph
->
check
=
0
;
if
(
skb
->
protocol
==
ETH_P_IPV6
)
{
ip6h
->
payload_len
=
0
;
tcph
->
check
=
~
csum_ipv6_magic
(
&
ip6h
->
saddr
,
&
ip6h
->
daddr
,
0
,
IPPROTO_TCP
,
0
);
return
;
}
/*OSA want us to set these values ...*/
tcph
->
check
=
~
csum_tcpudp_magic
(
iph
->
saddr
,
iph
->
daddr
,
0
,
IPPROTO_TCP
,
0
);
iph
->
tot_len
=
0
;
iph
->
check
=
0
;
}
static
inline
struct
qeth_hdr_tso
*
qeth_tso_prepare_packet
(
struct
qeth_card
*
card
,
struct
sk_buff
*
skb
,
int
ipv
,
int
cast_type
)
{
struct
qeth_hdr_tso
*
hdr
;
int
rc
=
0
;
QETH_DBF_TEXT
(
trace
,
5
,
"tsoprep"
);
/*get headroom for tso qdio header */
hdr
=
(
struct
qeth_hdr_tso
*
)
qeth_tso_prepare_skb
(
card
,
&
skb
);
if
(
hdr
==
NULL
)
{
QETH_DBF_TEXT_
(
trace
,
4
,
"2err%d"
,
rc
);
return
NULL
;
}
memset
(
hdr
,
0
,
sizeof
(
struct
qeth_hdr_tso
));
/*fill first 32 bytes of qdio header as used
*FIXME: TSO has two struct members
* with different names but same size
* */
qeth_fill_header
(
card
,
&
hdr
->
hdr
,
skb
,
ipv
,
cast_type
);
qeth_tso_fill_header
(
card
,
skb
);
qeth_tso_set_tcpip_header
(
card
,
skb
);
return
hdr
;
}
static
inline
int
qeth_tso_get_queue_buffer
(
struct
qeth_qdio_out_q
*
queue
)
{
struct
qeth_qdio_out_buffer
*
buffer
;
int
flush_cnt
=
0
;
QETH_DBF_TEXT
(
trace
,
5
,
"tsobuf"
);
/* force to non-packing*/
if
(
queue
->
do_pack
)
queue
->
do_pack
=
0
;
buffer
=
&
queue
->
bufs
[
queue
->
next_buf_to_fill
];
/* get a new buffer if current is already in use*/
if
((
atomic_read
(
&
buffer
->
state
)
==
QETH_QDIO_BUF_EMPTY
)
&&
(
buffer
->
next_element_to_fill
>
0
))
{
atomic_set
(
&
buffer
->
state
,
QETH_QDIO_BUF_PRIMED
);
queue
->
next_buf_to_fill
=
(
queue
->
next_buf_to_fill
+
1
)
%
QDIO_MAX_BUFFERS_PER_Q
;
flush_cnt
++
;
}
return
flush_cnt
;
}
static
inline
void
__qeth_tso_fill_buffer_frag
(
struct
qeth_qdio_out_buffer
*
buf
,
struct
sk_buff
*
skb
)
{
struct
skb_frag_struct
*
frag
;
struct
qdio_buffer
*
buffer
;
int
fragno
,
cnt
,
element
;
unsigned
long
addr
;
QETH_DBF_TEXT
(
trace
,
6
,
"tsfilfrg"
);
/*initialize variables ...*/
fragno
=
skb_shinfo
(
skb
)
->
nr_frags
;
buffer
=
buf
->
buffer
;
element
=
buf
->
next_element_to_fill
;
/*fill buffer elements .....*/
for
(
cnt
=
0
;
cnt
<
fragno
;
cnt
++
)
{
frag
=
&
skb_shinfo
(
skb
)
->
frags
[
cnt
];
addr
=
(
page_to_pfn
(
frag
->
page
)
<<
PAGE_SHIFT
)
+
frag
->
page_offset
;
buffer
->
element
[
element
].
addr
=
(
char
*
)
addr
;
buffer
->
element
[
element
].
length
=
frag
->
size
;
if
(
cnt
<
(
fragno
-
1
))
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_MIDDLE_FRAG
;
else
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_LAST_FRAG
;
element
++
;
}
buf
->
next_element_to_fill
=
element
;
}
static
inline
int
qeth_tso_fill_buffer
(
struct
qeth_qdio_out_buffer
*
buf
,
struct
sk_buff
*
skb
)
{
int
length
,
length_here
,
element
;
int
hdr_len
;
struct
qdio_buffer
*
buffer
;
struct
qeth_hdr_tso
*
hdr
;
char
*
data
;
QETH_DBF_TEXT
(
trace
,
3
,
"tsfilbuf"
);
/*increment user count and queue skb ...*/
atomic_inc
(
&
skb
->
users
);
skb_queue_tail
(
&
buf
->
skb_list
,
skb
);
/*initialize all variables...*/
buffer
=
buf
->
buffer
;
hdr
=
(
struct
qeth_hdr_tso
*
)
skb
->
data
;
hdr_len
=
sizeof
(
struct
qeth_hdr_tso
)
+
hdr
->
ext
.
dg_hdr_len
;
data
=
skb
->
data
+
hdr_len
;
length
=
skb
->
len
-
hdr_len
;
element
=
buf
->
next_element_to_fill
;
/*fill first buffer entry only with header information */
buffer
->
element
[
element
].
addr
=
skb
->
data
;
buffer
->
element
[
element
].
length
=
hdr_len
;
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_FIRST_FRAG
;
buf
->
next_element_to_fill
++
;
if
(
skb_shinfo
(
skb
)
->
nr_frags
>
0
)
{
__qeth_tso_fill_buffer_frag
(
buf
,
skb
);
goto
out
;
}
/*start filling buffer entries ...*/
element
++
;
while
(
length
>
0
)
{
/* length_here is the remaining amount of data in this page */
length_here
=
PAGE_SIZE
-
((
unsigned
long
)
data
%
PAGE_SIZE
);
if
(
length
<
length_here
)
length_here
=
length
;
buffer
->
element
[
element
].
addr
=
data
;
buffer
->
element
[
element
].
length
=
length_here
;
length
-=
length_here
;
if
(
!
length
)
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_LAST_FRAG
;
else
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_MIDDLE_FRAG
;
data
+=
length_here
;
element
++
;
}
/*set the buffer to primed ...*/
buf
->
next_element_to_fill
=
element
;
out:
atomic_set
(
&
buf
->
state
,
QETH_QDIO_BUF_PRIMED
);
return
1
;
}
int
qeth_tso_send_packet
(
struct
qeth_card
*
card
,
struct
sk_buff
*
skb
,
struct
qeth_qdio_out_q
*
queue
,
int
ipv
,
int
cast_type
)
{
int
flush_cnt
=
0
;
struct
qeth_hdr_tso
*
hdr
;
struct
qeth_qdio_out_buffer
*
buffer
;
int
start_index
;
QETH_DBF_TEXT
(
trace
,
3
,
"tsosend"
);
if
(
!
(
hdr
=
qeth_tso_prepare_packet
(
card
,
skb
,
ipv
,
cast_type
)))
return
-
ENOMEM
;
/*check if skb fits in one SBAL ...*/
if
(
!
(
qeth_get_elements_no
(
card
,
(
void
*
)
hdr
,
skb
)))
return
-
EINVAL
;
/*lock queue, force switching to non-packing and send it ...*/
while
(
atomic_compare_and_swap
(
QETH_OUT_Q_UNLOCKED
,
QETH_OUT_Q_LOCKED
,
&
queue
->
state
));
start_index
=
queue
->
next_buf_to_fill
;
buffer
=
&
queue
->
bufs
[
queue
->
next_buf_to_fill
];
/*check if card is too busy ...*/
if
(
atomic_read
(
&
buffer
->
state
)
!=
QETH_QDIO_BUF_EMPTY
){
card
->
stats
.
tx_dropped
++
;
goto
out
;
}
/*let's force to non-packing and get a new SBAL*/
flush_cnt
+=
qeth_tso_get_queue_buffer
(
queue
);
buffer
=
&
queue
->
bufs
[
queue
->
next_buf_to_fill
];
if
(
atomic_read
(
&
buffer
->
state
)
!=
QETH_QDIO_BUF_EMPTY
)
{
card
->
stats
.
tx_dropped
++
;
goto
out
;
}
flush_cnt
+=
qeth_tso_fill_buffer
(
buffer
,
skb
);
queue
->
next_buf_to_fill
=
(
queue
->
next_buf_to_fill
+
1
)
%
QDIO_MAX_BUFFERS_PER_Q
;
out:
atomic_set
(
&
queue
->
state
,
QETH_OUT_Q_UNLOCKED
);
if
(
flush_cnt
)
qeth_flush_buffers
(
queue
,
0
,
start_index
,
flush_cnt
);
/*do some statistics */
card
->
stats
.
tx_packets
++
;
card
->
stats
.
tx_bytes
+=
skb
->
len
;
return
0
;
}
drivers/s390/net/qeth_tso.h
View file @
8a75e7d6
/*
/*
* linux/drivers/s390/net/qeth_tso.h ($Revision: 1.
4
$)
* linux/drivers/s390/net/qeth_tso.h ($Revision: 1.
7
$)
*
*
* Header file for qeth TCP Segmentation Offload support.
* Header file for qeth TCP Segmentation Offload support.
*
*
...
@@ -7,52 +7,148 @@
...
@@ -7,52 +7,148 @@
*
*
* Author(s): Frank Pavlic <pavlic@de.ibm.com>
* Author(s): Frank Pavlic <pavlic@de.ibm.com>
*
*
* $Revision: 1.
4 $ $Date: 2005/03/24 09:04
:18 $
* $Revision: 1.
7 $ $Date: 2005/05/04 20:19
:18 $
*
*
*/
*/
#ifndef __QETH_TSO_H__
#ifndef __QETH_TSO_H__
#define __QETH_TSO_H__
#define __QETH_TSO_H__
#include <linux/skbuff.h>
#include <linux/tcp.h>
#include <linux/ip.h>
#include <linux/ipv6.h>
#include <net/ip6_checksum.h>
#include "qeth.h"
#include "qeth_mpc.h"
extern
int
qeth_tso_send_packet
(
struct
qeth_card
*
,
struct
sk_buff
*
,
struct
qeth_qdio_out_q
*
,
int
,
int
);
struct
qeth_hdr_ext_tso
{
static
inline
struct
qeth_hdr_tso
*
__u16
hdr_tot_len
;
qeth_tso_prepare_skb
(
struct
qeth_card
*
card
,
struct
sk_buff
**
skb
)
__u8
imb_hdr_no
;
{
__u8
reserved
;
QETH_DBF_TEXT
(
trace
,
5
,
"tsoprsk"
);
__u8
hdr_type
;
return
qeth_push_skb
(
card
,
skb
,
sizeof
(
struct
qeth_hdr_tso
));
__u8
hdr_version
;
}
__u16
hdr_len
;
__u32
payload_len
;
/**
__u16
mss
;
* fill header for a TSO packet
__u16
dg_hdr_len
;
*/
__u8
padding
[
16
];
static
inline
void
}
__attribute__
((
packed
));
qeth_tso_fill_header
(
struct
qeth_card
*
card
,
struct
sk_buff
*
skb
)
{
struct
qeth_hdr_tso
*
hdr
;
struct
tcphdr
*
tcph
;
struct
iphdr
*
iph
;
QETH_DBF_TEXT
(
trace
,
5
,
"tsofhdr"
);
hdr
=
(
struct
qeth_hdr_tso
*
)
skb
->
data
;
iph
=
skb
->
nh
.
iph
;
tcph
=
skb
->
h
.
th
;
/*fix header to TSO values ...*/
hdr
->
hdr
.
hdr
.
l3
.
id
=
QETH_HEADER_TYPE_TSO
;
/*set values which are fix for the first approach ...*/
hdr
->
ext
.
hdr_tot_len
=
(
__u16
)
sizeof
(
struct
qeth_hdr_ext_tso
);
hdr
->
ext
.
imb_hdr_no
=
1
;
hdr
->
ext
.
hdr_type
=
1
;
hdr
->
ext
.
hdr_version
=
1
;
hdr
->
ext
.
hdr_len
=
28
;
/*insert non-fix values */
hdr
->
ext
.
mss
=
skb_shinfo
(
skb
)
->
tso_size
;
hdr
->
ext
.
dg_hdr_len
=
(
__u16
)(
iph
->
ihl
*
4
+
tcph
->
doff
*
4
);
hdr
->
ext
.
payload_len
=
(
__u16
)(
skb
->
len
-
hdr
->
ext
.
dg_hdr_len
-
sizeof
(
struct
qeth_hdr_tso
));
}
/**
* change some header values as requested by hardware
*/
static
inline
void
qeth_tso_set_tcpip_header
(
struct
qeth_card
*
card
,
struct
sk_buff
*
skb
)
{
struct
iphdr
*
iph
;
struct
ipv6hdr
*
ip6h
;
struct
tcphdr
*
tcph
;
struct
qeth_hdr_tso
{
iph
=
skb
->
nh
.
iph
;
struct
qeth_hdr
hdr
;
/*hdr->hdr.l3.xxx*/
ip6h
=
skb
->
nh
.
ipv6h
;
struct
qeth_hdr_ext_tso
ext
;
tcph
=
skb
->
h
.
th
;
}
__attribute__
((
packed
));
/*some helper functions*/
tcph
->
check
=
0
;
if
(
skb
->
protocol
==
ETH_P_IPV6
)
{
ip6h
->
payload_len
=
0
;
tcph
->
check
=
~
csum_ipv6_magic
(
&
ip6h
->
saddr
,
&
ip6h
->
daddr
,
0
,
IPPROTO_TCP
,
0
);
return
;
}
/*OSA want us to set these values ...*/
tcph
->
check
=
~
csum_tcpudp_magic
(
iph
->
saddr
,
iph
->
daddr
,
0
,
IPPROTO_TCP
,
0
);
iph
->
tot_len
=
0
;
iph
->
check
=
0
;
}
static
inline
int
static
inline
int
qeth_get_elements_no
(
struct
qeth_card
*
card
,
void
*
hdr
,
struct
sk_buff
*
skb
)
qeth_tso_prepare_packet
(
struct
qeth_card
*
card
,
struct
sk_buff
*
skb
,
int
ipv
,
int
cast_type
)
{
{
int
elements_needed
=
0
;
struct
qeth_hdr_tso
*
hdr
;
if
(
skb_shinfo
(
skb
)
->
nr_frags
>
0
)
QETH_DBF_TEXT
(
trace
,
5
,
"tsoprep"
);
elements_needed
=
(
skb_shinfo
(
skb
)
->
nr_frags
+
1
);
if
(
elements_needed
==
0
)
hdr
=
(
struct
qeth_hdr_tso
*
)
qeth_tso_prepare_skb
(
card
,
&
skb
);
elements_needed
=
1
+
(((((
unsigned
long
)
hdr
)
%
PAGE_SIZE
)
if
(
hdr
==
NULL
)
{
+
skb
->
len
)
>>
PAGE_SHIFT
);
QETH_DBF_TEXT
(
trace
,
4
,
"tsoperr"
);
if
(
elements_needed
>
QETH_MAX_BUFFER_ELEMENTS
(
card
)){
return
-
ENOMEM
;
PRINT_ERR
(
"qeth_do_send_packet: invalid size of "
}
"IP packet. Discarded."
);
memset
(
hdr
,
0
,
sizeof
(
struct
qeth_hdr_tso
));
/*fill first 32 bytes of qdio header as used
*FIXME: TSO has two struct members
* with different names but same size
* */
qeth_fill_header
(
card
,
&
hdr
->
hdr
,
skb
,
ipv
,
cast_type
);
qeth_tso_fill_header
(
card
,
skb
);
qeth_tso_set_tcpip_header
(
card
,
skb
);
return
0
;
return
0
;
}
static
inline
void
__qeth_fill_buffer_frag
(
struct
sk_buff
*
skb
,
struct
qdio_buffer
*
buffer
,
int
is_tso
,
int
*
next_element_to_fill
)
{
struct
skb_frag_struct
*
frag
;
int
fragno
;
unsigned
long
addr
;
int
element
,
cnt
,
dlen
;
fragno
=
skb_shinfo
(
skb
)
->
nr_frags
;
element
=
*
next_element_to_fill
;
dlen
=
0
;
if
(
is_tso
)
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_MIDDLE_FRAG
;
else
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_FIRST_FRAG
;
if
(
(
dlen
=
(
skb
->
len
-
skb
->
data_len
))
)
{
buffer
->
element
[
element
].
addr
=
skb
->
data
;
buffer
->
element
[
element
].
length
=
dlen
;
element
++
;
}
for
(
cnt
=
0
;
cnt
<
fragno
;
cnt
++
)
{
frag
=
&
skb_shinfo
(
skb
)
->
frags
[
cnt
];
addr
=
(
page_to_pfn
(
frag
->
page
)
<<
PAGE_SHIFT
)
+
frag
->
page_offset
;
buffer
->
element
[
element
].
addr
=
(
char
*
)
addr
;
buffer
->
element
[
element
].
length
=
frag
->
size
;
if
(
cnt
<
(
fragno
-
1
))
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_MIDDLE_FRAG
;
else
buffer
->
element
[
element
].
flags
=
SBAL_FLAGS_LAST_FRAG
;
element
++
;
}
}
return
elements_needed
;
*
next_element_to_fill
=
element
;
}
}
#endif
/* __QETH_TSO_H__ */
#endif
/* __QETH_TSO_H__ */
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