qeth: remove old qeth files
Remove all obsolete qeth files. Signed-off-by: Frank Blaschka <frank.blaschka@de.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
This commit is contained in:
parent
4a71df5004
commit
19a3da6c6e
10 changed files with 0 additions and 14269 deletions
File diff suppressed because it is too large
Load diff
|
@ -1,634 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/s390/net/qeth_eddp.c
|
||||
*
|
||||
* Enhanced Device Driver Packing (EDDP) support for the qeth driver.
|
||||
*
|
||||
* Copyright 2004 IBM Corporation
|
||||
*
|
||||
* Author(s): Thomas Spatzier <tspat@de.ibm.com>
|
||||
*
|
||||
*/
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ip.h>
|
||||
#include <linux/inetdevice.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/tcp.h>
|
||||
#include <net/tcp.h>
|
||||
#include <linux/skbuff.h>
|
||||
|
||||
#include <net/ip.h>
|
||||
|
||||
#include "qeth.h"
|
||||
#include "qeth_mpc.h"
|
||||
#include "qeth_eddp.h"
|
||||
|
||||
int
|
||||
qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *queue,
|
||||
struct qeth_eddp_context *ctx)
|
||||
{
|
||||
int index = queue->next_buf_to_fill;
|
||||
int elements_needed = ctx->num_elements;
|
||||
int elements_in_buffer;
|
||||
int skbs_in_buffer;
|
||||
int buffers_needed = 0;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpcbfc");
|
||||
while(elements_needed > 0) {
|
||||
buffers_needed++;
|
||||
if (atomic_read(&queue->bufs[index].state) !=
|
||||
QETH_QDIO_BUF_EMPTY)
|
||||
return -EBUSY;
|
||||
|
||||
elements_in_buffer = QETH_MAX_BUFFER_ELEMENTS(queue->card) -
|
||||
queue->bufs[index].next_element_to_fill;
|
||||
skbs_in_buffer = elements_in_buffer / ctx->elements_per_skb;
|
||||
elements_needed -= skbs_in_buffer * ctx->elements_per_skb;
|
||||
index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
|
||||
}
|
||||
return buffers_needed;
|
||||
}
|
||||
|
||||
static void
|
||||
qeth_eddp_free_context(struct qeth_eddp_context *ctx)
|
||||
{
|
||||
int i;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpfctx");
|
||||
for (i = 0; i < ctx->num_pages; ++i)
|
||||
free_page((unsigned long)ctx->pages[i]);
|
||||
kfree(ctx->pages);
|
||||
kfree(ctx->elements);
|
||||
kfree(ctx);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
qeth_eddp_get_context(struct qeth_eddp_context *ctx)
|
||||
{
|
||||
atomic_inc(&ctx->refcnt);
|
||||
}
|
||||
|
||||
void
|
||||
qeth_eddp_put_context(struct qeth_eddp_context *ctx)
|
||||
{
|
||||
if (atomic_dec_return(&ctx->refcnt) == 0)
|
||||
qeth_eddp_free_context(ctx);
|
||||
}
|
||||
|
||||
void
|
||||
qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *buf)
|
||||
{
|
||||
struct qeth_eddp_context_reference *ref;
|
||||
|
||||
QETH_DBF_TEXT(trace, 6, "eddprctx");
|
||||
while (!list_empty(&buf->ctx_list)){
|
||||
ref = list_entry(buf->ctx_list.next,
|
||||
struct qeth_eddp_context_reference, list);
|
||||
qeth_eddp_put_context(ref->ctx);
|
||||
list_del(&ref->list);
|
||||
kfree(ref);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
qeth_eddp_buf_ref_context(struct qeth_qdio_out_buffer *buf,
|
||||
struct qeth_eddp_context *ctx)
|
||||
{
|
||||
struct qeth_eddp_context_reference *ref;
|
||||
|
||||
QETH_DBF_TEXT(trace, 6, "eddprfcx");
|
||||
ref = kmalloc(sizeof(struct qeth_eddp_context_reference), GFP_ATOMIC);
|
||||
if (ref == NULL)
|
||||
return -ENOMEM;
|
||||
qeth_eddp_get_context(ctx);
|
||||
ref->ctx = ctx;
|
||||
list_add_tail(&ref->list, &buf->ctx_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
qeth_eddp_fill_buffer(struct qeth_qdio_out_q *queue,
|
||||
struct qeth_eddp_context *ctx,
|
||||
int index)
|
||||
{
|
||||
struct qeth_qdio_out_buffer *buf = NULL;
|
||||
struct qdio_buffer *buffer;
|
||||
int elements = ctx->num_elements;
|
||||
int element = 0;
|
||||
int flush_cnt = 0;
|
||||
int must_refcnt = 1;
|
||||
int i;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpfibu");
|
||||
while (elements > 0) {
|
||||
buf = &queue->bufs[index];
|
||||
if (atomic_read(&buf->state) != QETH_QDIO_BUF_EMPTY){
|
||||
/* normally this should not happen since we checked for
|
||||
* available elements in qeth_check_elements_for_context
|
||||
*/
|
||||
if (element == 0)
|
||||
return -EBUSY;
|
||||
else {
|
||||
PRINT_WARN("could only partially fill eddp "
|
||||
"buffer!\n");
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
/* check if the whole next skb fits into current buffer */
|
||||
if ((QETH_MAX_BUFFER_ELEMENTS(queue->card) -
|
||||
buf->next_element_to_fill)
|
||||
< ctx->elements_per_skb){
|
||||
/* no -> go to next buffer */
|
||||
atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
|
||||
index = (index + 1) % QDIO_MAX_BUFFERS_PER_Q;
|
||||
flush_cnt++;
|
||||
/* new buffer, so we have to add ctx to buffer'ctx_list
|
||||
* and increment ctx's refcnt */
|
||||
must_refcnt = 1;
|
||||
continue;
|
||||
}
|
||||
if (must_refcnt){
|
||||
must_refcnt = 0;
|
||||
if (qeth_eddp_buf_ref_context(buf, ctx)){
|
||||
PRINT_WARN("no memory to create eddp context "
|
||||
"reference\n");
|
||||
goto out_check;
|
||||
}
|
||||
}
|
||||
buffer = buf->buffer;
|
||||
/* fill one skb into buffer */
|
||||
for (i = 0; i < ctx->elements_per_skb; ++i){
|
||||
if (ctx->elements[element].length != 0) {
|
||||
buffer->element[buf->next_element_to_fill].
|
||||
addr = ctx->elements[element].addr;
|
||||
buffer->element[buf->next_element_to_fill].
|
||||
length = ctx->elements[element].length;
|
||||
buffer->element[buf->next_element_to_fill].
|
||||
flags = ctx->elements[element].flags;
|
||||
buf->next_element_to_fill++;
|
||||
}
|
||||
element++;
|
||||
elements--;
|
||||
}
|
||||
}
|
||||
out_check:
|
||||
if (!queue->do_pack) {
|
||||
QETH_DBF_TEXT(trace, 6, "fillbfnp");
|
||||
/* set state to PRIMED -> will be flushed */
|
||||
if (buf->next_element_to_fill > 0){
|
||||
atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
|
||||
flush_cnt++;
|
||||
}
|
||||
} else {
|
||||
if (queue->card->options.performance_stats)
|
||||
queue->card->perf_stats.skbs_sent_pack++;
|
||||
QETH_DBF_TEXT(trace, 6, "fillbfpa");
|
||||
if (buf->next_element_to_fill >=
|
||||
QETH_MAX_BUFFER_ELEMENTS(queue->card)) {
|
||||
/*
|
||||
* packed buffer if full -> set state PRIMED
|
||||
* -> will be flushed
|
||||
*/
|
||||
atomic_set(&buf->state, QETH_QDIO_BUF_PRIMED);
|
||||
flush_cnt++;
|
||||
}
|
||||
}
|
||||
out:
|
||||
return flush_cnt;
|
||||
}
|
||||
|
||||
static void
|
||||
qeth_eddp_create_segment_hdrs(struct qeth_eddp_context *ctx,
|
||||
struct qeth_eddp_data *eddp, int data_len)
|
||||
{
|
||||
u8 *page;
|
||||
int page_remainder;
|
||||
int page_offset;
|
||||
int pkt_len;
|
||||
struct qeth_eddp_element *element;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpcrsh");
|
||||
page = ctx->pages[ctx->offset >> PAGE_SHIFT];
|
||||
page_offset = ctx->offset % PAGE_SIZE;
|
||||
element = &ctx->elements[ctx->num_elements];
|
||||
pkt_len = eddp->nhl + eddp->thl + data_len;
|
||||
/* FIXME: layer2 and VLAN !!! */
|
||||
if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2)
|
||||
pkt_len += ETH_HLEN;
|
||||
if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
|
||||
pkt_len += VLAN_HLEN;
|
||||
/* does complete packet fit in current page ? */
|
||||
page_remainder = PAGE_SIZE - page_offset;
|
||||
if (page_remainder < (sizeof(struct qeth_hdr) + pkt_len)){
|
||||
/* no -> go to start of next page */
|
||||
ctx->offset += page_remainder;
|
||||
page = ctx->pages[ctx->offset >> PAGE_SHIFT];
|
||||
page_offset = 0;
|
||||
}
|
||||
memcpy(page + page_offset, &eddp->qh, sizeof(struct qeth_hdr));
|
||||
element->addr = page + page_offset;
|
||||
element->length = sizeof(struct qeth_hdr);
|
||||
ctx->offset += sizeof(struct qeth_hdr);
|
||||
page_offset += sizeof(struct qeth_hdr);
|
||||
/* add mac header (?) */
|
||||
if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
|
||||
memcpy(page + page_offset, &eddp->mac, ETH_HLEN);
|
||||
element->length += ETH_HLEN;
|
||||
ctx->offset += ETH_HLEN;
|
||||
page_offset += ETH_HLEN;
|
||||
}
|
||||
/* add VLAN tag */
|
||||
if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)){
|
||||
memcpy(page + page_offset, &eddp->vlan, VLAN_HLEN);
|
||||
element->length += VLAN_HLEN;
|
||||
ctx->offset += VLAN_HLEN;
|
||||
page_offset += VLAN_HLEN;
|
||||
}
|
||||
/* add network header */
|
||||
memcpy(page + page_offset, (u8 *)&eddp->nh, eddp->nhl);
|
||||
element->length += eddp->nhl;
|
||||
eddp->nh_in_ctx = page + page_offset;
|
||||
ctx->offset += eddp->nhl;
|
||||
page_offset += eddp->nhl;
|
||||
/* add transport header */
|
||||
memcpy(page + page_offset, (u8 *)&eddp->th, eddp->thl);
|
||||
element->length += eddp->thl;
|
||||
eddp->th_in_ctx = page + page_offset;
|
||||
ctx->offset += eddp->thl;
|
||||
}
|
||||
|
||||
static void
|
||||
qeth_eddp_copy_data_tcp(char *dst, struct qeth_eddp_data *eddp, int len,
|
||||
__wsum *hcsum)
|
||||
{
|
||||
struct skb_frag_struct *frag;
|
||||
int left_in_frag;
|
||||
int copy_len;
|
||||
u8 *src;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpcdtc");
|
||||
if (skb_shinfo(eddp->skb)->nr_frags == 0) {
|
||||
skb_copy_from_linear_data_offset(eddp->skb, eddp->skb_offset,
|
||||
dst, len);
|
||||
*hcsum = csum_partial(eddp->skb->data + eddp->skb_offset, len,
|
||||
*hcsum);
|
||||
eddp->skb_offset += len;
|
||||
} else {
|
||||
while (len > 0) {
|
||||
if (eddp->frag < 0) {
|
||||
/* we're in skb->data */
|
||||
left_in_frag = (eddp->skb->len - eddp->skb->data_len)
|
||||
- eddp->skb_offset;
|
||||
src = eddp->skb->data + eddp->skb_offset;
|
||||
} else {
|
||||
frag = &skb_shinfo(eddp->skb)->
|
||||
frags[eddp->frag];
|
||||
left_in_frag = frag->size - eddp->frag_offset;
|
||||
src = (u8 *)(
|
||||
(page_to_pfn(frag->page) << PAGE_SHIFT)+
|
||||
frag->page_offset + eddp->frag_offset);
|
||||
}
|
||||
if (left_in_frag <= 0) {
|
||||
eddp->frag++;
|
||||
eddp->frag_offset = 0;
|
||||
continue;
|
||||
}
|
||||
copy_len = min(left_in_frag, len);
|
||||
memcpy(dst, src, copy_len);
|
||||
*hcsum = csum_partial(src, copy_len, *hcsum);
|
||||
dst += copy_len;
|
||||
eddp->frag_offset += copy_len;
|
||||
eddp->skb_offset += copy_len;
|
||||
len -= copy_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qeth_eddp_create_segment_data_tcp(struct qeth_eddp_context *ctx,
|
||||
struct qeth_eddp_data *eddp, int data_len,
|
||||
__wsum hcsum)
|
||||
{
|
||||
u8 *page;
|
||||
int page_remainder;
|
||||
int page_offset;
|
||||
struct qeth_eddp_element *element;
|
||||
int first_lap = 1;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpcsdt");
|
||||
page = ctx->pages[ctx->offset >> PAGE_SHIFT];
|
||||
page_offset = ctx->offset % PAGE_SIZE;
|
||||
element = &ctx->elements[ctx->num_elements];
|
||||
while (data_len){
|
||||
page_remainder = PAGE_SIZE - page_offset;
|
||||
if (page_remainder < data_len){
|
||||
qeth_eddp_copy_data_tcp(page + page_offset, eddp,
|
||||
page_remainder, &hcsum);
|
||||
element->length += page_remainder;
|
||||
if (first_lap)
|
||||
element->flags = SBAL_FLAGS_FIRST_FRAG;
|
||||
else
|
||||
element->flags = SBAL_FLAGS_MIDDLE_FRAG;
|
||||
ctx->num_elements++;
|
||||
element++;
|
||||
data_len -= page_remainder;
|
||||
ctx->offset += page_remainder;
|
||||
page = ctx->pages[ctx->offset >> PAGE_SHIFT];
|
||||
page_offset = 0;
|
||||
element->addr = page + page_offset;
|
||||
} else {
|
||||
qeth_eddp_copy_data_tcp(page + page_offset, eddp,
|
||||
data_len, &hcsum);
|
||||
element->length += data_len;
|
||||
if (!first_lap)
|
||||
element->flags = SBAL_FLAGS_LAST_FRAG;
|
||||
ctx->num_elements++;
|
||||
ctx->offset += data_len;
|
||||
data_len = 0;
|
||||
}
|
||||
first_lap = 0;
|
||||
}
|
||||
((struct tcphdr *)eddp->th_in_ctx)->check = csum_fold(hcsum);
|
||||
}
|
||||
|
||||
static __wsum
|
||||
qeth_eddp_check_tcp4_hdr(struct qeth_eddp_data *eddp, int data_len)
|
||||
{
|
||||
__wsum phcsum; /* pseudo header checksum */
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpckt4");
|
||||
eddp->th.tcp.h.check = 0;
|
||||
/* compute pseudo header checksum */
|
||||
phcsum = csum_tcpudp_nofold(eddp->nh.ip4.h.saddr, eddp->nh.ip4.h.daddr,
|
||||
eddp->thl + data_len, IPPROTO_TCP, 0);
|
||||
/* compute checksum of tcp header */
|
||||
return csum_partial((u8 *)&eddp->th, eddp->thl, phcsum);
|
||||
}
|
||||
|
||||
static __wsum
|
||||
qeth_eddp_check_tcp6_hdr(struct qeth_eddp_data *eddp, int data_len)
|
||||
{
|
||||
__be32 proto;
|
||||
__wsum phcsum; /* pseudo header checksum */
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpckt6");
|
||||
eddp->th.tcp.h.check = 0;
|
||||
/* compute pseudo header checksum */
|
||||
phcsum = csum_partial((u8 *)&eddp->nh.ip6.h.saddr,
|
||||
sizeof(struct in6_addr), 0);
|
||||
phcsum = csum_partial((u8 *)&eddp->nh.ip6.h.daddr,
|
||||
sizeof(struct in6_addr), phcsum);
|
||||
proto = htonl(IPPROTO_TCP);
|
||||
phcsum = csum_partial((u8 *)&proto, sizeof(u32), phcsum);
|
||||
return phcsum;
|
||||
}
|
||||
|
||||
static struct qeth_eddp_data *
|
||||
qeth_eddp_create_eddp_data(struct qeth_hdr *qh, u8 *nh, u8 nhl, u8 *th, u8 thl)
|
||||
{
|
||||
struct qeth_eddp_data *eddp;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpcrda");
|
||||
eddp = kzalloc(sizeof(struct qeth_eddp_data), GFP_ATOMIC);
|
||||
if (eddp){
|
||||
eddp->nhl = nhl;
|
||||
eddp->thl = thl;
|
||||
memcpy(&eddp->qh, qh, sizeof(struct qeth_hdr));
|
||||
memcpy(&eddp->nh, nh, nhl);
|
||||
memcpy(&eddp->th, th, thl);
|
||||
eddp->frag = -1; /* initially we're in skb->data */
|
||||
}
|
||||
return eddp;
|
||||
}
|
||||
|
||||
static void
|
||||
__qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
|
||||
struct qeth_eddp_data *eddp)
|
||||
{
|
||||
struct tcphdr *tcph;
|
||||
int data_len;
|
||||
__wsum hcsum;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpftcp");
|
||||
eddp->skb_offset = sizeof(struct qeth_hdr) + eddp->nhl + eddp->thl;
|
||||
if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
|
||||
eddp->skb_offset += sizeof(struct ethhdr);
|
||||
#ifdef CONFIG_QETH_VLAN
|
||||
if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
|
||||
eddp->skb_offset += VLAN_HLEN;
|
||||
#endif /* CONFIG_QETH_VLAN */
|
||||
}
|
||||
tcph = tcp_hdr(eddp->skb);
|
||||
while (eddp->skb_offset < eddp->skb->len) {
|
||||
data_len = min((int)skb_shinfo(eddp->skb)->gso_size,
|
||||
(int)(eddp->skb->len - eddp->skb_offset));
|
||||
/* prepare qdio hdr */
|
||||
if (eddp->qh.hdr.l2.id == QETH_HEADER_TYPE_LAYER2){
|
||||
eddp->qh.hdr.l2.pkt_length = data_len + ETH_HLEN +
|
||||
eddp->nhl + eddp->thl;
|
||||
#ifdef CONFIG_QETH_VLAN
|
||||
if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q))
|
||||
eddp->qh.hdr.l2.pkt_length += VLAN_HLEN;
|
||||
#endif /* CONFIG_QETH_VLAN */
|
||||
} else
|
||||
eddp->qh.hdr.l3.length = data_len + eddp->nhl +
|
||||
eddp->thl;
|
||||
/* prepare ip hdr */
|
||||
if (eddp->skb->protocol == htons(ETH_P_IP)){
|
||||
eddp->nh.ip4.h.tot_len = htons(data_len + eddp->nhl +
|
||||
eddp->thl);
|
||||
eddp->nh.ip4.h.check = 0;
|
||||
eddp->nh.ip4.h.check =
|
||||
ip_fast_csum((u8 *)&eddp->nh.ip4.h,
|
||||
eddp->nh.ip4.h.ihl);
|
||||
} else
|
||||
eddp->nh.ip6.h.payload_len = htons(data_len + eddp->thl);
|
||||
/* prepare tcp hdr */
|
||||
if (data_len == (eddp->skb->len - eddp->skb_offset)){
|
||||
/* last segment -> set FIN and PSH flags */
|
||||
eddp->th.tcp.h.fin = tcph->fin;
|
||||
eddp->th.tcp.h.psh = tcph->psh;
|
||||
}
|
||||
if (eddp->skb->protocol == htons(ETH_P_IP))
|
||||
hcsum = qeth_eddp_check_tcp4_hdr(eddp, data_len);
|
||||
else
|
||||
hcsum = qeth_eddp_check_tcp6_hdr(eddp, data_len);
|
||||
/* fill the next segment into the context */
|
||||
qeth_eddp_create_segment_hdrs(ctx, eddp, data_len);
|
||||
qeth_eddp_create_segment_data_tcp(ctx, eddp, data_len, hcsum);
|
||||
if (eddp->skb_offset >= eddp->skb->len)
|
||||
break;
|
||||
/* prepare headers for next round */
|
||||
if (eddp->skb->protocol == htons(ETH_P_IP))
|
||||
eddp->nh.ip4.h.id = htons(ntohs(eddp->nh.ip4.h.id) + 1);
|
||||
eddp->th.tcp.h.seq = htonl(ntohl(eddp->th.tcp.h.seq) + data_len);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
qeth_eddp_fill_context_tcp(struct qeth_eddp_context *ctx,
|
||||
struct sk_buff *skb, struct qeth_hdr *qhdr)
|
||||
{
|
||||
struct qeth_eddp_data *eddp = NULL;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpficx");
|
||||
/* create our segmentation headers and copy original headers */
|
||||
if (skb->protocol == htons(ETH_P_IP))
|
||||
eddp = qeth_eddp_create_eddp_data(qhdr,
|
||||
skb_network_header(skb),
|
||||
ip_hdrlen(skb),
|
||||
skb_transport_header(skb),
|
||||
tcp_hdrlen(skb));
|
||||
else
|
||||
eddp = qeth_eddp_create_eddp_data(qhdr,
|
||||
skb_network_header(skb),
|
||||
sizeof(struct ipv6hdr),
|
||||
skb_transport_header(skb),
|
||||
tcp_hdrlen(skb));
|
||||
|
||||
if (eddp == NULL) {
|
||||
QETH_DBF_TEXT(trace, 2, "eddpfcnm");
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (qhdr->hdr.l2.id == QETH_HEADER_TYPE_LAYER2) {
|
||||
skb_set_mac_header(skb, sizeof(struct qeth_hdr));
|
||||
memcpy(&eddp->mac, eth_hdr(skb), ETH_HLEN);
|
||||
#ifdef CONFIG_QETH_VLAN
|
||||
if (eddp->mac.h_proto == __constant_htons(ETH_P_8021Q)) {
|
||||
eddp->vlan[0] = skb->protocol;
|
||||
eddp->vlan[1] = htons(vlan_tx_tag_get(skb));
|
||||
}
|
||||
#endif /* CONFIG_QETH_VLAN */
|
||||
}
|
||||
/* the next flags will only be set on the last segment */
|
||||
eddp->th.tcp.h.fin = 0;
|
||||
eddp->th.tcp.h.psh = 0;
|
||||
eddp->skb = skb;
|
||||
/* begin segmentation and fill context */
|
||||
__qeth_eddp_fill_context_tcp(ctx, eddp);
|
||||
kfree(eddp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
qeth_eddp_calc_num_pages(struct qeth_eddp_context *ctx, struct sk_buff *skb,
|
||||
int hdr_len)
|
||||
{
|
||||
int skbs_per_page;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "eddpcanp");
|
||||
/* can we put multiple skbs in one page? */
|
||||
skbs_per_page = PAGE_SIZE / (skb_shinfo(skb)->gso_size + hdr_len);
|
||||
if (skbs_per_page > 1){
|
||||
ctx->num_pages = (skb_shinfo(skb)->gso_segs + 1) /
|
||||
skbs_per_page + 1;
|
||||
ctx->elements_per_skb = 1;
|
||||
} else {
|
||||
/* no -> how many elements per skb? */
|
||||
ctx->elements_per_skb = (skb_shinfo(skb)->gso_size + hdr_len +
|
||||
PAGE_SIZE) >> PAGE_SHIFT;
|
||||
ctx->num_pages = ctx->elements_per_skb *
|
||||
(skb_shinfo(skb)->gso_segs + 1);
|
||||
}
|
||||
ctx->num_elements = ctx->elements_per_skb *
|
||||
(skb_shinfo(skb)->gso_segs + 1);
|
||||
}
|
||||
|
||||
static struct qeth_eddp_context *
|
||||
qeth_eddp_create_context_generic(struct qeth_card *card, struct sk_buff *skb,
|
||||
int hdr_len)
|
||||
{
|
||||
struct qeth_eddp_context *ctx = NULL;
|
||||
u8 *addr;
|
||||
int i;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "creddpcg");
|
||||
/* create the context and allocate pages */
|
||||
ctx = kzalloc(sizeof(struct qeth_eddp_context), GFP_ATOMIC);
|
||||
if (ctx == NULL){
|
||||
QETH_DBF_TEXT(trace, 2, "ceddpcn1");
|
||||
return NULL;
|
||||
}
|
||||
ctx->type = QETH_LARGE_SEND_EDDP;
|
||||
qeth_eddp_calc_num_pages(ctx, skb, hdr_len);
|
||||
if (ctx->elements_per_skb > QETH_MAX_BUFFER_ELEMENTS(card)){
|
||||
QETH_DBF_TEXT(trace, 2, "ceddpcis");
|
||||
kfree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
ctx->pages = kcalloc(ctx->num_pages, sizeof(u8 *), GFP_ATOMIC);
|
||||
if (ctx->pages == NULL){
|
||||
QETH_DBF_TEXT(trace, 2, "ceddpcn2");
|
||||
kfree(ctx);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < ctx->num_pages; ++i){
|
||||
addr = (u8 *)__get_free_page(GFP_ATOMIC);
|
||||
if (addr == NULL){
|
||||
QETH_DBF_TEXT(trace, 2, "ceddpcn3");
|
||||
ctx->num_pages = i;
|
||||
qeth_eddp_free_context(ctx);
|
||||
return NULL;
|
||||
}
|
||||
memset(addr, 0, PAGE_SIZE);
|
||||
ctx->pages[i] = addr;
|
||||
}
|
||||
ctx->elements = kcalloc(ctx->num_elements,
|
||||
sizeof(struct qeth_eddp_element), GFP_ATOMIC);
|
||||
if (ctx->elements == NULL){
|
||||
QETH_DBF_TEXT(trace, 2, "ceddpcn4");
|
||||
qeth_eddp_free_context(ctx);
|
||||
return NULL;
|
||||
}
|
||||
/* reset num_elements; will be incremented again in fill_buffer to
|
||||
* reflect number of actually used elements */
|
||||
ctx->num_elements = 0;
|
||||
return ctx;
|
||||
}
|
||||
|
||||
static struct qeth_eddp_context *
|
||||
qeth_eddp_create_context_tcp(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_hdr *qhdr)
|
||||
{
|
||||
struct qeth_eddp_context *ctx = NULL;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "creddpct");
|
||||
if (skb->protocol == htons(ETH_P_IP))
|
||||
ctx = qeth_eddp_create_context_generic(card, skb,
|
||||
(sizeof(struct qeth_hdr) +
|
||||
ip_hdrlen(skb) +
|
||||
tcp_hdrlen(skb)));
|
||||
else if (skb->protocol == htons(ETH_P_IPV6))
|
||||
ctx = qeth_eddp_create_context_generic(card, skb,
|
||||
sizeof(struct qeth_hdr) + sizeof(struct ipv6hdr) +
|
||||
tcp_hdrlen(skb));
|
||||
else
|
||||
QETH_DBF_TEXT(trace, 2, "cetcpinv");
|
||||
|
||||
if (ctx == NULL) {
|
||||
QETH_DBF_TEXT(trace, 2, "creddpnl");
|
||||
return NULL;
|
||||
}
|
||||
if (qeth_eddp_fill_context_tcp(ctx, skb, qhdr)){
|
||||
QETH_DBF_TEXT(trace, 2, "ceddptfe");
|
||||
qeth_eddp_free_context(ctx);
|
||||
return NULL;
|
||||
}
|
||||
atomic_set(&ctx->refcnt, 1);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
struct qeth_eddp_context *
|
||||
qeth_eddp_create_context(struct qeth_card *card, struct sk_buff *skb,
|
||||
struct qeth_hdr *qhdr, unsigned char sk_protocol)
|
||||
{
|
||||
QETH_DBF_TEXT(trace, 5, "creddpc");
|
||||
switch (sk_protocol) {
|
||||
case IPPROTO_TCP:
|
||||
return qeth_eddp_create_context_tcp(card, skb, qhdr);
|
||||
default:
|
||||
QETH_DBF_TEXT(trace, 2, "eddpinvp");
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/s390/net/qeth_eddp.h
|
||||
*
|
||||
* Header file for qeth enhanced device driver packing.
|
||||
*
|
||||
* Copyright 2004 IBM Corporation
|
||||
*
|
||||
* Author(s): Thomas Spatzier <tspat@de.ibm.com>
|
||||
*
|
||||
*/
|
||||
#ifndef __QETH_EDDP_H__
|
||||
#define __QETH_EDDP_H__
|
||||
|
||||
struct qeth_eddp_element {
|
||||
u32 flags;
|
||||
u32 length;
|
||||
void *addr;
|
||||
};
|
||||
|
||||
struct qeth_eddp_context {
|
||||
atomic_t refcnt;
|
||||
enum qeth_large_send_types type;
|
||||
int num_pages; /* # of allocated pages */
|
||||
u8 **pages; /* pointers to pages */
|
||||
int offset; /* offset in ctx during creation */
|
||||
int num_elements; /* # of required 'SBALEs' */
|
||||
struct qeth_eddp_element *elements; /* array of 'SBALEs' */
|
||||
int elements_per_skb; /* # of 'SBALEs' per skb **/
|
||||
};
|
||||
|
||||
struct qeth_eddp_context_reference {
|
||||
struct list_head list;
|
||||
struct qeth_eddp_context *ctx;
|
||||
};
|
||||
|
||||
extern struct qeth_eddp_context *
|
||||
qeth_eddp_create_context(struct qeth_card *,struct sk_buff *,
|
||||
struct qeth_hdr *, unsigned char);
|
||||
|
||||
extern void
|
||||
qeth_eddp_put_context(struct qeth_eddp_context *);
|
||||
|
||||
extern int
|
||||
qeth_eddp_fill_buffer(struct qeth_qdio_out_q *,struct qeth_eddp_context *,int);
|
||||
|
||||
extern void
|
||||
qeth_eddp_buf_release_contexts(struct qeth_qdio_out_buffer *);
|
||||
|
||||
extern int
|
||||
qeth_eddp_check_buffers_for_context(struct qeth_qdio_out_q *,
|
||||
struct qeth_eddp_context *);
|
||||
/*
|
||||
* Data used for fragmenting a IP packet.
|
||||
*/
|
||||
struct qeth_eddp_data {
|
||||
struct qeth_hdr qh;
|
||||
struct ethhdr mac;
|
||||
__be16 vlan[2];
|
||||
union {
|
||||
struct {
|
||||
struct iphdr h;
|
||||
u8 options[40];
|
||||
} ip4;
|
||||
struct {
|
||||
struct ipv6hdr h;
|
||||
} ip6;
|
||||
} nh;
|
||||
u8 nhl;
|
||||
void *nh_in_ctx; /* address of nh within the ctx */
|
||||
union {
|
||||
struct {
|
||||
struct tcphdr h;
|
||||
u8 options[40];
|
||||
} tcp;
|
||||
} th;
|
||||
u8 thl;
|
||||
void *th_in_ctx; /* address of th within the ctx */
|
||||
struct sk_buff *skb;
|
||||
int skb_offset;
|
||||
int frag;
|
||||
int frag_offset;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* __QETH_EDDP_H__ */
|
|
@ -1,168 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/s390/net/qeth_fs.h
|
||||
*
|
||||
* Linux on zSeries OSA Express and HiperSockets support.
|
||||
*
|
||||
* This header file contains definitions related to sysfs and procfs.
|
||||
*
|
||||
* Copyright 2000,2003 IBM Corporation
|
||||
* Author(s): Thomas Spatzier <tspat@de.ibm.com>
|
||||
*
|
||||
*/
|
||||
#ifndef __QETH_FS_H__
|
||||
#define __QETH_FS_H__
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
extern int
|
||||
qeth_create_procfs_entries(void);
|
||||
|
||||
extern void
|
||||
qeth_remove_procfs_entries(void);
|
||||
#else
|
||||
static inline int
|
||||
qeth_create_procfs_entries(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
qeth_remove_procfs_entries(void)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_PROC_FS */
|
||||
|
||||
extern int
|
||||
qeth_create_device_attributes(struct device *dev);
|
||||
|
||||
extern void
|
||||
qeth_remove_device_attributes(struct device *dev);
|
||||
|
||||
extern int
|
||||
qeth_create_device_attributes_osn(struct device *dev);
|
||||
|
||||
extern void
|
||||
qeth_remove_device_attributes_osn(struct device *dev);
|
||||
|
||||
extern int
|
||||
qeth_create_driver_attributes(void);
|
||||
|
||||
extern void
|
||||
qeth_remove_driver_attributes(void);
|
||||
|
||||
/*
|
||||
* utility functions used in qeth_proc.c and qeth_sys.c
|
||||
*/
|
||||
|
||||
static inline const char *
|
||||
qeth_get_checksum_str(struct qeth_card *card)
|
||||
{
|
||||
if (card->options.checksum_type == SW_CHECKSUMMING)
|
||||
return "sw";
|
||||
else if (card->options.checksum_type == HW_CHECKSUMMING)
|
||||
return "hw";
|
||||
else
|
||||
return "no";
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
qeth_get_prioq_str(struct qeth_card *card, char *buf)
|
||||
{
|
||||
if (card->qdio.do_prio_queueing == QETH_NO_PRIO_QUEUEING)
|
||||
sprintf(buf, "always_q_%i", card->qdio.default_out_queue);
|
||||
else
|
||||
strcpy(buf, (card->qdio.do_prio_queueing ==
|
||||
QETH_PRIO_Q_ING_PREC)?
|
||||
"by_prec." : "by_ToS");
|
||||
return buf;
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
qeth_get_bufsize_str(struct qeth_card *card)
|
||||
{
|
||||
if (card->qdio.in_buf_size == 16384)
|
||||
return "16k";
|
||||
else if (card->qdio.in_buf_size == 24576)
|
||||
return "24k";
|
||||
else if (card->qdio.in_buf_size == 32768)
|
||||
return "32k";
|
||||
else if (card->qdio.in_buf_size == 40960)
|
||||
return "40k";
|
||||
else
|
||||
return "64k";
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
qeth_get_cardname(struct qeth_card *card)
|
||||
{
|
||||
if (card->info.guestlan) {
|
||||
switch (card->info.type) {
|
||||
case QETH_CARD_TYPE_OSAE:
|
||||
return " Guest LAN QDIO";
|
||||
case QETH_CARD_TYPE_IQD:
|
||||
return " Guest LAN Hiper";
|
||||
default:
|
||||
return " unknown";
|
||||
}
|
||||
} else {
|
||||
switch (card->info.type) {
|
||||
case QETH_CARD_TYPE_OSAE:
|
||||
return " OSD Express";
|
||||
case QETH_CARD_TYPE_IQD:
|
||||
return " HiperSockets";
|
||||
case QETH_CARD_TYPE_OSN:
|
||||
return " OSN QDIO";
|
||||
default:
|
||||
return " unknown";
|
||||
}
|
||||
}
|
||||
return " n/a";
|
||||
}
|
||||
|
||||
/* max length to be returned: 14 */
|
||||
static inline const char *
|
||||
qeth_get_cardname_short(struct qeth_card *card)
|
||||
{
|
||||
if (card->info.guestlan){
|
||||
switch (card->info.type){
|
||||
case QETH_CARD_TYPE_OSAE:
|
||||
return "GuestLAN QDIO";
|
||||
case QETH_CARD_TYPE_IQD:
|
||||
return "GuestLAN Hiper";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
} else {
|
||||
switch (card->info.type) {
|
||||
case QETH_CARD_TYPE_OSAE:
|
||||
switch (card->info.link_type) {
|
||||
case QETH_LINK_TYPE_FAST_ETH:
|
||||
return "OSD_100";
|
||||
case QETH_LINK_TYPE_HSTR:
|
||||
return "HSTR";
|
||||
case QETH_LINK_TYPE_GBIT_ETH:
|
||||
return "OSD_1000";
|
||||
case QETH_LINK_TYPE_10GBIT_ETH:
|
||||
return "OSD_10GIG";
|
||||
case QETH_LINK_TYPE_LANE_ETH100:
|
||||
return "OSD_FE_LANE";
|
||||
case QETH_LINK_TYPE_LANE_TR:
|
||||
return "OSD_TR_LANE";
|
||||
case QETH_LINK_TYPE_LANE_ETH1000:
|
||||
return "OSD_GbE_LANE";
|
||||
case QETH_LINK_TYPE_LANE:
|
||||
return "OSD_ATM_LANE";
|
||||
default:
|
||||
return "OSD_Express";
|
||||
}
|
||||
case QETH_CARD_TYPE_IQD:
|
||||
return "HiperSockets";
|
||||
case QETH_CARD_TYPE_OSN:
|
||||
return "OSN";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
return "n/a";
|
||||
}
|
||||
|
||||
#endif /* __QETH_FS_H__ */
|
File diff suppressed because it is too large
Load diff
|
@ -1,269 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/s390/net/qeth_mpc.c
|
||||
*
|
||||
* Linux on zSeries OSA Express and HiperSockets support
|
||||
*
|
||||
* Copyright 2000,2003 IBM Corporation
|
||||
* Author(s): Frank Pavlic <fpavlic@de.ibm.com>
|
||||
* Thomas Spatzier <tspat@de.ibm.com>
|
||||
*
|
||||
*/
|
||||
#include <asm/cio.h>
|
||||
#include "qeth_mpc.h"
|
||||
|
||||
unsigned char IDX_ACTIVATE_READ[]={
|
||||
0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x19,0x01,0x01,0x80, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0xc8,0xc1,
|
||||
0xd3,0xd3,0xd6,0xd3, 0xc5,0x40,0x00,0x00,
|
||||
0x00,0x00
|
||||
};
|
||||
|
||||
unsigned char IDX_ACTIVATE_WRITE[]={
|
||||
0x00,0x00,0x80,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x15,0x01,0x01,0x80, 0x00,0x00,0x00,0x00,
|
||||
0xff,0xff,0x00,0x00, 0x00,0x00,0xc8,0xc1,
|
||||
0xd3,0xd3,0xd6,0xd3, 0xc5,0x40,0x00,0x00,
|
||||
0x00,0x00
|
||||
};
|
||||
|
||||
unsigned char CM_ENABLE[]={
|
||||
0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x01,
|
||||
0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x63,
|
||||
0x10,0x00,0x00,0x01,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x81,0x7e,0x00,0x01, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x23,
|
||||
0x00,0x00,0x23,0x05, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,0x00,0x23, 0x00,0x00,0x00,0x40,
|
||||
0x00,0x0c,0x41,0x02, 0x00,0x17,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x00,0x0b,0x04,0x01,
|
||||
0x7e,0x04,0x05,0x00, 0x01,0x01,0x0f,
|
||||
0x00,
|
||||
0x0c,0x04,0x02,0xff, 0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff
|
||||
};
|
||||
|
||||
unsigned char CM_SETUP[]={
|
||||
0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x02,
|
||||
0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x64,
|
||||
0x10,0x00,0x00,0x01,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x81,0x7e,0x00,0x01, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x24,
|
||||
0x00,0x00,0x24,0x05, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,0x00,0x24, 0x00,0x00,0x00,0x40,
|
||||
0x00,0x0c,0x41,0x04, 0x00,0x18,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x00,0x09,0x04,0x04,
|
||||
0x05,0x00,0x01,0x01, 0x11,
|
||||
0x00,0x09,0x04,
|
||||
0x05,0x05,0x00,0x00, 0x00,0x00,
|
||||
0x00,0x06,
|
||||
0x04,0x06,0xc8,0x00
|
||||
};
|
||||
|
||||
unsigned char ULP_ENABLE[]={
|
||||
0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x03,
|
||||
0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x6b,
|
||||
0x10,0x00,0x00,0x01,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x01,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x24,0x00,0x2b,
|
||||
0x00,0x00,0x2b,0x05, 0x20,0x01,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,0x00,0x2b, 0x00,0x00,0x00,0x40,
|
||||
0x00,0x0c,0x41,0x02, 0x00,0x1f,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x00,0x0b,0x04,0x01,
|
||||
0x03,0x04,0x05,0x00, 0x01,0x01,0x12,
|
||||
0x00,
|
||||
0x14,0x04,0x0a,0x00, 0x20,0x00,0x00,0xff,
|
||||
0xff,0x00,0x08,0xc8, 0xe8,0xc4,0xf1,0xc7,
|
||||
0xf1,0x00,0x00
|
||||
};
|
||||
|
||||
unsigned char ULP_SETUP[]={
|
||||
0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x04,
|
||||
0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x6c,
|
||||
0x10,0x00,0x00,0x01,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x02,
|
||||
0x00,0x00,0x00,0x01, 0x00,0x24,0x00,0x2c,
|
||||
0x00,0x00,0x2c,0x05, 0x20,0x01,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,0x00,0x2c, 0x00,0x00,0x00,0x40,
|
||||
0x00,0x0c,0x41,0x04, 0x00,0x20,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x00,0x09,0x04,0x04,
|
||||
0x05,0x00,0x01,0x01, 0x14,
|
||||
0x00,0x09,0x04,
|
||||
0x05,0x05,0x30,0x01, 0x00,0x00,
|
||||
0x00,0x06,
|
||||
0x04,0x06,0x40,0x00,
|
||||
0x00,0x08,0x04,0x0b,
|
||||
0x00,0x00,0x00,0x00
|
||||
};
|
||||
|
||||
unsigned char DM_ACT[]={
|
||||
0x00,0xe0,0x00,0x00, 0x00,0x00,0x00,0x05,
|
||||
0x00,0x00,0x00,0x14, 0x00,0x00,0x00,0x55,
|
||||
0x10,0x00,0x00,0x01,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x41,0x7e,0x00,0x01, 0x00,0x00,0x00,0x03,
|
||||
0x00,0x00,0x00,0x02, 0x00,0x24,0x00,0x15,
|
||||
0x00,0x00,0x2c,0x05, 0x20,0x01,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,0x00,0x15, 0x00,0x00,0x00,0x40,
|
||||
0x00,0x0c,0x43,0x60, 0x00,0x09,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,
|
||||
0x00,0x09,0x04,0x04,
|
||||
0x05,0x40,0x01,0x01, 0x00
|
||||
};
|
||||
|
||||
unsigned char IPA_PDU_HEADER[]={
|
||||
0x00,0xe0,0x00,0x00, 0x77,0x77,0x77,0x77,
|
||||
0x00,0x00,0x00,0x14, 0x00,0x00,
|
||||
(IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))/256,
|
||||
(IPA_PDU_HEADER_SIZE+sizeof(struct qeth_ipa_cmd))%256,
|
||||
0x10,0x00,0x00,0x01, 0x00,0x00,0x00,0x00,
|
||||
0xc1,0x03,0x00,0x01, 0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x24,
|
||||
sizeof(struct qeth_ipa_cmd)/256,
|
||||
sizeof(struct qeth_ipa_cmd)%256,
|
||||
0x00,
|
||||
sizeof(struct qeth_ipa_cmd)/256,
|
||||
sizeof(struct qeth_ipa_cmd)%256,
|
||||
0x05,
|
||||
0x77,0x77,0x77,0x77,
|
||||
0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,
|
||||
0x01,0x00,
|
||||
sizeof(struct qeth_ipa_cmd)/256,
|
||||
sizeof(struct qeth_ipa_cmd)%256,
|
||||
0x00,0x00,0x00,0x40,
|
||||
};
|
||||
|
||||
unsigned char WRITE_CCW[]={
|
||||
0x01,CCW_FLAG_SLI,0,0,
|
||||
0,0,0,0
|
||||
};
|
||||
|
||||
unsigned char READ_CCW[]={
|
||||
0x02,CCW_FLAG_SLI,0,0,
|
||||
0,0,0,0
|
||||
};
|
||||
|
||||
|
||||
struct ipa_rc_msg {
|
||||
enum qeth_ipa_return_codes rc;
|
||||
char *msg;
|
||||
};
|
||||
|
||||
static struct ipa_rc_msg qeth_ipa_rc_msg[] = {
|
||||
{IPA_RC_SUCCESS, "success"},
|
||||
{IPA_RC_NOTSUPP, "Command not supported"},
|
||||
{IPA_RC_IP_TABLE_FULL, "Add Addr IP Table Full - ipv6"},
|
||||
{IPA_RC_UNKNOWN_ERROR, "IPA command failed - reason unknown"},
|
||||
{IPA_RC_UNSUPPORTED_COMMAND, "Command not supported"},
|
||||
{IPA_RC_DUP_IPV6_REMOTE,"ipv6 address already registered remote"},
|
||||
{IPA_RC_DUP_IPV6_HOME, "ipv6 address already registered"},
|
||||
{IPA_RC_UNREGISTERED_ADDR, "Address not registered"},
|
||||
{IPA_RC_NO_ID_AVAILABLE, "No identifiers available"},
|
||||
{IPA_RC_ID_NOT_FOUND, "Identifier not found"},
|
||||
{IPA_RC_INVALID_IP_VERSION, "IP version incorrect"},
|
||||
{IPA_RC_LAN_FRAME_MISMATCH, "LAN and frame mismatch"},
|
||||
{IPA_RC_L2_UNSUPPORTED_CMD, "Unsupported layer 2 command"},
|
||||
{IPA_RC_L2_DUP_MAC, "Duplicate MAC address"},
|
||||
{IPA_RC_L2_ADDR_TABLE_FULL, "Layer2 address table full"},
|
||||
{IPA_RC_L2_DUP_LAYER3_MAC, "Duplicate with layer 3 MAC"},
|
||||
{IPA_RC_L2_GMAC_NOT_FOUND, "GMAC not found"},
|
||||
{IPA_RC_L2_MAC_NOT_FOUND, "L2 mac address not found"},
|
||||
{IPA_RC_L2_INVALID_VLAN_ID, "L2 invalid vlan id"},
|
||||
{IPA_RC_L2_DUP_VLAN_ID, "L2 duplicate vlan id"},
|
||||
{IPA_RC_L2_VLAN_ID_NOT_FOUND, "L2 vlan id not found"},
|
||||
{IPA_RC_DATA_MISMATCH, "Data field mismatch (v4/v6 mixed)"},
|
||||
{IPA_RC_INVALID_MTU_SIZE, "Invalid MTU size"},
|
||||
{IPA_RC_INVALID_LANTYPE, "Invalid LAN type"},
|
||||
{IPA_RC_INVALID_LANNUM, "Invalid LAN num"},
|
||||
{IPA_RC_DUPLICATE_IP_ADDRESS, "Address already registered"},
|
||||
{IPA_RC_IP_ADDR_TABLE_FULL, "IP address table full"},
|
||||
{IPA_RC_LAN_PORT_STATE_ERROR, "LAN port state error"},
|
||||
{IPA_RC_SETIP_NO_STARTLAN, "Setip no startlan received"},
|
||||
{IPA_RC_SETIP_ALREADY_RECEIVED, "Setip already received"},
|
||||
{IPA_RC_IP_ADDR_ALREADY_USED, "IP address already in use on LAN"},
|
||||
{IPA_RC_MULTICAST_FULL, "No task available, multicast full"},
|
||||
{IPA_RC_SETIP_INVALID_VERSION, "SETIP invalid IP version"},
|
||||
{IPA_RC_UNSUPPORTED_SUBCMD, "Unsupported assist subcommand"},
|
||||
{IPA_RC_ARP_ASSIST_NO_ENABLE, "Only partial success, no enable"},
|
||||
{IPA_RC_PRIMARY_ALREADY_DEFINED,"Primary already defined"},
|
||||
{IPA_RC_SECOND_ALREADY_DEFINED, "Secondary already defined"},
|
||||
{IPA_RC_INVALID_SETRTG_INDICATOR,"Invalid SETRTG indicator"},
|
||||
{IPA_RC_MC_ADDR_ALREADY_DEFINED,"Multicast address already defined"},
|
||||
{IPA_RC_LAN_OFFLINE, "STRTLAN_LAN_DISABLED - LAN offline"},
|
||||
{IPA_RC_INVALID_IP_VERSION2, "Invalid IP version"},
|
||||
{IPA_RC_FFFF, "Unknown Error"}
|
||||
};
|
||||
|
||||
|
||||
|
||||
char *
|
||||
qeth_get_ipa_msg(enum qeth_ipa_return_codes rc)
|
||||
{
|
||||
int x = 0;
|
||||
qeth_ipa_rc_msg[sizeof(qeth_ipa_rc_msg) /
|
||||
sizeof(struct ipa_rc_msg) - 1].rc = rc;
|
||||
while(qeth_ipa_rc_msg[x].rc != rc)
|
||||
x++;
|
||||
return qeth_ipa_rc_msg[x].msg;
|
||||
}
|
||||
|
||||
|
||||
struct ipa_cmd_names {
|
||||
enum qeth_ipa_cmds cmd;
|
||||
char *name;
|
||||
};
|
||||
|
||||
static struct ipa_cmd_names qeth_ipa_cmd_names[] = {
|
||||
{IPA_CMD_STARTLAN, "startlan"},
|
||||
{IPA_CMD_STOPLAN, "stoplan"},
|
||||
{IPA_CMD_SETVMAC, "setvmac"},
|
||||
{IPA_CMD_DELVMAC, "delvmca"},
|
||||
{IPA_CMD_SETGMAC, "setgmac"},
|
||||
{IPA_CMD_DELGMAC, "delgmac"},
|
||||
{IPA_CMD_SETVLAN, "setvlan"},
|
||||
{IPA_CMD_DELVLAN, "delvlan"},
|
||||
{IPA_CMD_SETCCID, "setccid"},
|
||||
{IPA_CMD_DELCCID, "delccid"},
|
||||
{IPA_CMD_MODCCID, "setip"},
|
||||
{IPA_CMD_SETIP, "setip"},
|
||||
{IPA_CMD_QIPASSIST, "qipassist"},
|
||||
{IPA_CMD_SETASSPARMS, "setassparms"},
|
||||
{IPA_CMD_SETIPM, "setipm"},
|
||||
{IPA_CMD_DELIPM, "delipm"},
|
||||
{IPA_CMD_SETRTG, "setrtg"},
|
||||
{IPA_CMD_DELIP, "delip"},
|
||||
{IPA_CMD_SETADAPTERPARMS, "setadapterparms"},
|
||||
{IPA_CMD_SET_DIAG_ASS, "set_diag_ass"},
|
||||
{IPA_CMD_CREATE_ADDR, "create_addr"},
|
||||
{IPA_CMD_DESTROY_ADDR, "destroy_addr"},
|
||||
{IPA_CMD_REGISTER_LOCAL_ADDR, "register_local_addr"},
|
||||
{IPA_CMD_UNREGISTER_LOCAL_ADDR, "unregister_local_addr"},
|
||||
{IPA_CMD_UNKNOWN, "unknown"},
|
||||
};
|
||||
|
||||
char *
|
||||
qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd)
|
||||
{
|
||||
int x = 0;
|
||||
qeth_ipa_cmd_names[
|
||||
sizeof(qeth_ipa_cmd_names)/
|
||||
sizeof(struct ipa_cmd_names)-1].cmd = cmd;
|
||||
while(qeth_ipa_cmd_names[x].cmd != cmd)
|
||||
x++;
|
||||
return qeth_ipa_cmd_names[x].name;
|
||||
}
|
||||
|
||||
|
|
@ -1,583 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/s390/net/qeth_mpc.h
|
||||
*
|
||||
* Linux on zSeries OSA Express and HiperSockets support
|
||||
*
|
||||
* Copyright 2000,2003 IBM Corporation
|
||||
* Author(s): Utz Bacher <utz.bacher@de.ibm.com>
|
||||
* Thomas Spatzier <tspat@de.ibm.com>
|
||||
* Frank Pavlic <fpavlic@de.ibm.com>
|
||||
*
|
||||
*/
|
||||
#ifndef __QETH_MPC_H__
|
||||
#define __QETH_MPC_H__
|
||||
|
||||
#include <asm/qeth.h>
|
||||
|
||||
#define IPA_PDU_HEADER_SIZE 0x40
|
||||
#define QETH_IPA_PDU_LEN_TOTAL(buffer) (buffer+0x0e)
|
||||
#define QETH_IPA_PDU_LEN_PDU1(buffer) (buffer+0x26)
|
||||
#define QETH_IPA_PDU_LEN_PDU2(buffer) (buffer+0x29)
|
||||
#define QETH_IPA_PDU_LEN_PDU3(buffer) (buffer+0x3a)
|
||||
|
||||
extern unsigned char IPA_PDU_HEADER[];
|
||||
#define QETH_IPA_CMD_DEST_ADDR(buffer) (buffer+0x2c)
|
||||
|
||||
#define IPA_CMD_LENGTH (IPA_PDU_HEADER_SIZE + sizeof(struct qeth_ipa_cmd))
|
||||
|
||||
#define QETH_SEQ_NO_LENGTH 4
|
||||
#define QETH_MPC_TOKEN_LENGTH 4
|
||||
#define QETH_MCL_LENGTH 4
|
||||
#define OSA_ADDR_LEN 6
|
||||
|
||||
#define QETH_TIMEOUT (10 * HZ)
|
||||
#define QETH_IPA_TIMEOUT (45 * HZ)
|
||||
#define QETH_IDX_COMMAND_SEQNO 0xffff0000
|
||||
#define SR_INFO_LEN 16
|
||||
|
||||
#define QETH_CLEAR_CHANNEL_PARM -10
|
||||
#define QETH_HALT_CHANNEL_PARM -11
|
||||
#define QETH_RCD_PARM -12
|
||||
|
||||
/*****************************************************************************/
|
||||
/* IP Assist related definitions */
|
||||
/*****************************************************************************/
|
||||
#define IPA_CMD_INITIATOR_HOST 0x00
|
||||
#define IPA_CMD_INITIATOR_OSA 0x01
|
||||
#define IPA_CMD_INITIATOR_HOST_REPLY 0x80
|
||||
#define IPA_CMD_INITIATOR_OSA_REPLY 0x81
|
||||
#define IPA_CMD_PRIM_VERSION_NO 0x01
|
||||
|
||||
enum qeth_card_types {
|
||||
QETH_CARD_TYPE_UNKNOWN = 0,
|
||||
QETH_CARD_TYPE_OSAE = 10,
|
||||
QETH_CARD_TYPE_IQD = 1234,
|
||||
QETH_CARD_TYPE_OSN = 11,
|
||||
};
|
||||
|
||||
#define QETH_MPC_DIFINFO_LEN_INDICATES_LINK_TYPE 0x18
|
||||
/* only the first two bytes are looked at in qeth_get_cardname_short */
|
||||
enum qeth_link_types {
|
||||
QETH_LINK_TYPE_FAST_ETH = 0x01,
|
||||
QETH_LINK_TYPE_HSTR = 0x02,
|
||||
QETH_LINK_TYPE_GBIT_ETH = 0x03,
|
||||
QETH_LINK_TYPE_OSN = 0x04,
|
||||
QETH_LINK_TYPE_10GBIT_ETH = 0x10,
|
||||
QETH_LINK_TYPE_LANE_ETH100 = 0x81,
|
||||
QETH_LINK_TYPE_LANE_TR = 0x82,
|
||||
QETH_LINK_TYPE_LANE_ETH1000 = 0x83,
|
||||
QETH_LINK_TYPE_LANE = 0x88,
|
||||
QETH_LINK_TYPE_ATM_NATIVE = 0x90,
|
||||
};
|
||||
|
||||
enum qeth_tr_macaddr_modes {
|
||||
QETH_TR_MACADDR_NONCANONICAL = 0,
|
||||
QETH_TR_MACADDR_CANONICAL = 1,
|
||||
};
|
||||
|
||||
enum qeth_tr_broadcast_modes {
|
||||
QETH_TR_BROADCAST_ALLRINGS = 0,
|
||||
QETH_TR_BROADCAST_LOCAL = 1,
|
||||
};
|
||||
|
||||
/* these values match CHECKSUM_* in include/linux/skbuff.h */
|
||||
enum qeth_checksum_types {
|
||||
SW_CHECKSUMMING = 0, /* TODO: set to bit flag used in IPA Command */
|
||||
HW_CHECKSUMMING = 1,
|
||||
NO_CHECKSUMMING = 2,
|
||||
};
|
||||
#define QETH_CHECKSUM_DEFAULT SW_CHECKSUMMING
|
||||
|
||||
/*
|
||||
* Routing stuff
|
||||
*/
|
||||
#define RESET_ROUTING_FLAG 0x10 /* indicate that routing type shall be set */
|
||||
enum qeth_routing_types {
|
||||
NO_ROUTER = 0, /* TODO: set to bit flag used in IPA Command */
|
||||
PRIMARY_ROUTER = 1,
|
||||
SECONDARY_ROUTER = 2,
|
||||
MULTICAST_ROUTER = 3,
|
||||
PRIMARY_CONNECTOR = 4,
|
||||
SECONDARY_CONNECTOR = 5,
|
||||
};
|
||||
|
||||
/* IPA Commands */
|
||||
enum qeth_ipa_cmds {
|
||||
IPA_CMD_STARTLAN = 0x01,
|
||||
IPA_CMD_STOPLAN = 0x02,
|
||||
IPA_CMD_SETVMAC = 0x21,
|
||||
IPA_CMD_DELVMAC = 0x22,
|
||||
IPA_CMD_SETGMAC = 0x23,
|
||||
IPA_CMD_DELGMAC = 0x24,
|
||||
IPA_CMD_SETVLAN = 0x25,
|
||||
IPA_CMD_DELVLAN = 0x26,
|
||||
IPA_CMD_SETCCID = 0x41,
|
||||
IPA_CMD_DELCCID = 0x42,
|
||||
IPA_CMD_MODCCID = 0x43,
|
||||
IPA_CMD_SETIP = 0xb1,
|
||||
IPA_CMD_QIPASSIST = 0xb2,
|
||||
IPA_CMD_SETASSPARMS = 0xb3,
|
||||
IPA_CMD_SETIPM = 0xb4,
|
||||
IPA_CMD_DELIPM = 0xb5,
|
||||
IPA_CMD_SETRTG = 0xb6,
|
||||
IPA_CMD_DELIP = 0xb7,
|
||||
IPA_CMD_SETADAPTERPARMS = 0xb8,
|
||||
IPA_CMD_SET_DIAG_ASS = 0xb9,
|
||||
IPA_CMD_CREATE_ADDR = 0xc3,
|
||||
IPA_CMD_DESTROY_ADDR = 0xc4,
|
||||
IPA_CMD_REGISTER_LOCAL_ADDR = 0xd1,
|
||||
IPA_CMD_UNREGISTER_LOCAL_ADDR = 0xd2,
|
||||
IPA_CMD_UNKNOWN = 0x00
|
||||
};
|
||||
|
||||
enum qeth_ip_ass_cmds {
|
||||
IPA_CMD_ASS_START = 0x0001,
|
||||
IPA_CMD_ASS_STOP = 0x0002,
|
||||
IPA_CMD_ASS_CONFIGURE = 0x0003,
|
||||
IPA_CMD_ASS_ENABLE = 0x0004,
|
||||
};
|
||||
|
||||
enum qeth_arp_process_subcmds {
|
||||
IPA_CMD_ASS_ARP_SET_NO_ENTRIES = 0x0003,
|
||||
IPA_CMD_ASS_ARP_QUERY_CACHE = 0x0004,
|
||||
IPA_CMD_ASS_ARP_ADD_ENTRY = 0x0005,
|
||||
IPA_CMD_ASS_ARP_REMOVE_ENTRY = 0x0006,
|
||||
IPA_CMD_ASS_ARP_FLUSH_CACHE = 0x0007,
|
||||
IPA_CMD_ASS_ARP_QUERY_INFO = 0x0104,
|
||||
IPA_CMD_ASS_ARP_QUERY_STATS = 0x0204,
|
||||
};
|
||||
|
||||
|
||||
/* Return Codes for IPA Commands
|
||||
* according to OSA card Specs */
|
||||
|
||||
enum qeth_ipa_return_codes {
|
||||
IPA_RC_SUCCESS = 0x0000,
|
||||
IPA_RC_NOTSUPP = 0x0001,
|
||||
IPA_RC_IP_TABLE_FULL = 0x0002,
|
||||
IPA_RC_UNKNOWN_ERROR = 0x0003,
|
||||
IPA_RC_UNSUPPORTED_COMMAND = 0x0004,
|
||||
IPA_RC_DUP_IPV6_REMOTE = 0x0008,
|
||||
IPA_RC_DUP_IPV6_HOME = 0x0010,
|
||||
IPA_RC_UNREGISTERED_ADDR = 0x0011,
|
||||
IPA_RC_NO_ID_AVAILABLE = 0x0012,
|
||||
IPA_RC_ID_NOT_FOUND = 0x0013,
|
||||
IPA_RC_INVALID_IP_VERSION = 0x0020,
|
||||
IPA_RC_LAN_FRAME_MISMATCH = 0x0040,
|
||||
IPA_RC_L2_UNSUPPORTED_CMD = 0x2003,
|
||||
IPA_RC_L2_DUP_MAC = 0x2005,
|
||||
IPA_RC_L2_ADDR_TABLE_FULL = 0x2006,
|
||||
IPA_RC_L2_DUP_LAYER3_MAC = 0x200a,
|
||||
IPA_RC_L2_GMAC_NOT_FOUND = 0x200b,
|
||||
IPA_RC_L2_MAC_NOT_FOUND = 0x2010,
|
||||
IPA_RC_L2_INVALID_VLAN_ID = 0x2015,
|
||||
IPA_RC_L2_DUP_VLAN_ID = 0x2016,
|
||||
IPA_RC_L2_VLAN_ID_NOT_FOUND = 0x2017,
|
||||
IPA_RC_DATA_MISMATCH = 0xe001,
|
||||
IPA_RC_INVALID_MTU_SIZE = 0xe002,
|
||||
IPA_RC_INVALID_LANTYPE = 0xe003,
|
||||
IPA_RC_INVALID_LANNUM = 0xe004,
|
||||
IPA_RC_DUPLICATE_IP_ADDRESS = 0xe005,
|
||||
IPA_RC_IP_ADDR_TABLE_FULL = 0xe006,
|
||||
IPA_RC_LAN_PORT_STATE_ERROR = 0xe007,
|
||||
IPA_RC_SETIP_NO_STARTLAN = 0xe008,
|
||||
IPA_RC_SETIP_ALREADY_RECEIVED = 0xe009,
|
||||
IPA_RC_IP_ADDR_ALREADY_USED = 0xe00a,
|
||||
IPA_RC_MULTICAST_FULL = 0xe00b,
|
||||
IPA_RC_SETIP_INVALID_VERSION = 0xe00d,
|
||||
IPA_RC_UNSUPPORTED_SUBCMD = 0xe00e,
|
||||
IPA_RC_ARP_ASSIST_NO_ENABLE = 0xe00f,
|
||||
IPA_RC_PRIMARY_ALREADY_DEFINED = 0xe010,
|
||||
IPA_RC_SECOND_ALREADY_DEFINED = 0xe011,
|
||||
IPA_RC_INVALID_SETRTG_INDICATOR = 0xe012,
|
||||
IPA_RC_MC_ADDR_ALREADY_DEFINED = 0xe013,
|
||||
IPA_RC_LAN_OFFLINE = 0xe080,
|
||||
IPA_RC_INVALID_IP_VERSION2 = 0xf001,
|
||||
IPA_RC_FFFF = 0xffff
|
||||
};
|
||||
|
||||
/* IPA function flags; each flag marks availability of respective function */
|
||||
enum qeth_ipa_funcs {
|
||||
IPA_ARP_PROCESSING = 0x00000001L,
|
||||
IPA_INBOUND_CHECKSUM = 0x00000002L,
|
||||
IPA_OUTBOUND_CHECKSUM = 0x00000004L,
|
||||
IPA_IP_FRAGMENTATION = 0x00000008L,
|
||||
IPA_FILTERING = 0x00000010L,
|
||||
IPA_IPV6 = 0x00000020L,
|
||||
IPA_MULTICASTING = 0x00000040L,
|
||||
IPA_IP_REASSEMBLY = 0x00000080L,
|
||||
IPA_QUERY_ARP_COUNTERS = 0x00000100L,
|
||||
IPA_QUERY_ARP_ADDR_INFO = 0x00000200L,
|
||||
IPA_SETADAPTERPARMS = 0x00000400L,
|
||||
IPA_VLAN_PRIO = 0x00000800L,
|
||||
IPA_PASSTHRU = 0x00001000L,
|
||||
IPA_FLUSH_ARP_SUPPORT = 0x00002000L,
|
||||
IPA_FULL_VLAN = 0x00004000L,
|
||||
IPA_INBOUND_PASSTHRU = 0x00008000L,
|
||||
IPA_SOURCE_MAC = 0x00010000L,
|
||||
IPA_OSA_MC_ROUTER = 0x00020000L,
|
||||
IPA_QUERY_ARP_ASSIST = 0x00040000L,
|
||||
IPA_INBOUND_TSO = 0x00080000L,
|
||||
IPA_OUTBOUND_TSO = 0x00100000L,
|
||||
};
|
||||
|
||||
/* SETIP/DELIP IPA Command: ***************************************************/
|
||||
enum qeth_ipa_setdelip_flags {
|
||||
QETH_IPA_SETDELIP_DEFAULT = 0x00L, /* default */
|
||||
QETH_IPA_SETIP_VIPA_FLAG = 0x01L, /* no grat. ARP */
|
||||
QETH_IPA_SETIP_TAKEOVER_FLAG = 0x02L, /* nofail on grat. ARP */
|
||||
QETH_IPA_DELIP_ADDR_2_B_TAKEN_OVER = 0x20L,
|
||||
QETH_IPA_DELIP_VIPA_FLAG = 0x40L,
|
||||
QETH_IPA_DELIP_ADDR_NEEDS_SETIP = 0x80L,
|
||||
};
|
||||
|
||||
/* SETADAPTER IPA Command: ****************************************************/
|
||||
enum qeth_ipa_setadp_cmd {
|
||||
IPA_SETADP_QUERY_COMMANDS_SUPPORTED = 0x01,
|
||||
IPA_SETADP_ALTER_MAC_ADDRESS = 0x02,
|
||||
IPA_SETADP_ADD_DELETE_GROUP_ADDRESS = 0x04,
|
||||
IPA_SETADP_ADD_DELETE_FUNCTIONAL_ADDR = 0x08,
|
||||
IPA_SETADP_SET_ADDRESSING_MODE = 0x10,
|
||||
IPA_SETADP_SET_CONFIG_PARMS = 0x20,
|
||||
IPA_SETADP_SET_CONFIG_PARMS_EXTENDED = 0x40,
|
||||
IPA_SETADP_SET_BROADCAST_MODE = 0x80,
|
||||
IPA_SETADP_SEND_OSA_MESSAGE = 0x0100,
|
||||
IPA_SETADP_SET_SNMP_CONTROL = 0x0200,
|
||||
IPA_SETADP_QUERY_CARD_INFO = 0x0400,
|
||||
IPA_SETADP_SET_PROMISC_MODE = 0x0800,
|
||||
};
|
||||
enum qeth_ipa_mac_ops {
|
||||
CHANGE_ADDR_READ_MAC = 0,
|
||||
CHANGE_ADDR_REPLACE_MAC = 1,
|
||||
CHANGE_ADDR_ADD_MAC = 2,
|
||||
CHANGE_ADDR_DEL_MAC = 4,
|
||||
CHANGE_ADDR_RESET_MAC = 8,
|
||||
};
|
||||
enum qeth_ipa_addr_ops {
|
||||
CHANGE_ADDR_READ_ADDR = 0,
|
||||
CHANGE_ADDR_ADD_ADDR = 1,
|
||||
CHANGE_ADDR_DEL_ADDR = 2,
|
||||
CHANGE_ADDR_FLUSH_ADDR_TABLE = 4,
|
||||
};
|
||||
enum qeth_ipa_promisc_modes {
|
||||
SET_PROMISC_MODE_OFF = 0,
|
||||
SET_PROMISC_MODE_ON = 1,
|
||||
};
|
||||
|
||||
/* (SET)DELIP(M) IPA stuff ***************************************************/
|
||||
struct qeth_ipacmd_setdelip4 {
|
||||
__u8 ip_addr[4];
|
||||
__u8 mask[4];
|
||||
__u32 flags;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct qeth_ipacmd_setdelip6 {
|
||||
__u8 ip_addr[16];
|
||||
__u8 mask[16];
|
||||
__u32 flags;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct qeth_ipacmd_setdelipm {
|
||||
__u8 mac[6];
|
||||
__u8 padding[2];
|
||||
__u8 ip6[12];
|
||||
__u8 ip4[4];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct qeth_ipacmd_layer2setdelmac {
|
||||
__u32 mac_length;
|
||||
__u8 mac[6];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct qeth_ipacmd_layer2setdelvlan {
|
||||
__u16 vlan_id;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct qeth_ipacmd_setassparms_hdr {
|
||||
__u32 assist_no;
|
||||
__u16 length;
|
||||
__u16 command_code;
|
||||
__u16 return_code;
|
||||
__u8 number_of_replies;
|
||||
__u8 seq_no;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct qeth_arp_query_data {
|
||||
__u16 request_bits;
|
||||
__u16 reply_bits;
|
||||
__u32 no_entries;
|
||||
char data;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* used as parameter for arp_query reply */
|
||||
struct qeth_arp_query_info {
|
||||
__u32 udata_len;
|
||||
__u16 mask_bits;
|
||||
__u32 udata_offset;
|
||||
__u32 no_entries;
|
||||
char *udata;
|
||||
};
|
||||
|
||||
/* SETASSPARMS IPA Command: */
|
||||
struct qeth_ipacmd_setassparms {
|
||||
struct qeth_ipacmd_setassparms_hdr hdr;
|
||||
union {
|
||||
__u32 flags_32bit;
|
||||
struct qeth_arp_cache_entry add_arp_entry;
|
||||
struct qeth_arp_query_data query_arp;
|
||||
__u8 ip[16];
|
||||
} data;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
/* SETRTG IPA Command: ****************************************************/
|
||||
struct qeth_set_routing {
|
||||
__u8 type;
|
||||
};
|
||||
|
||||
/* SETADAPTERPARMS IPA Command: *******************************************/
|
||||
struct qeth_query_cmds_supp {
|
||||
__u32 no_lantypes_supp;
|
||||
__u8 lan_type;
|
||||
__u8 reserved1[3];
|
||||
__u32 supported_cmds;
|
||||
__u8 reserved2[8];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct qeth_change_addr {
|
||||
__u32 cmd;
|
||||
__u32 addr_size;
|
||||
__u32 no_macs;
|
||||
__u8 addr[OSA_ADDR_LEN];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
|
||||
struct qeth_snmp_cmd {
|
||||
__u8 token[16];
|
||||
__u32 request;
|
||||
__u32 interface;
|
||||
__u32 returncode;
|
||||
__u32 firmwarelevel;
|
||||
__u32 seqno;
|
||||
__u8 data;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct qeth_snmp_ureq_hdr {
|
||||
__u32 data_len;
|
||||
__u32 req_len;
|
||||
__u32 reserved1;
|
||||
__u32 reserved2;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct qeth_snmp_ureq {
|
||||
struct qeth_snmp_ureq_hdr hdr;
|
||||
struct qeth_snmp_cmd cmd;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct qeth_ipacmd_setadpparms_hdr {
|
||||
__u32 supp_hw_cmds;
|
||||
__u32 reserved1;
|
||||
__u16 cmdlength;
|
||||
__u16 reserved2;
|
||||
__u32 command_code;
|
||||
__u16 return_code;
|
||||
__u8 used_total;
|
||||
__u8 seq_no;
|
||||
__u32 reserved3;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct qeth_ipacmd_setadpparms {
|
||||
struct qeth_ipacmd_setadpparms_hdr hdr;
|
||||
union {
|
||||
struct qeth_query_cmds_supp query_cmds_supp;
|
||||
struct qeth_change_addr change_addr;
|
||||
struct qeth_snmp_cmd snmp;
|
||||
__u32 mode;
|
||||
} data;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* IPFRAME IPA Command: ***************************************************/
|
||||
/* TODO: define in analogy to commands define above */
|
||||
|
||||
/* ADD_ADDR_ENTRY IPA Command: ********************************************/
|
||||
/* TODO: define in analogy to commands define above */
|
||||
|
||||
/* DELETE_ADDR_ENTRY IPA Command: *****************************************/
|
||||
/* TODO: define in analogy to commands define above */
|
||||
|
||||
/* CREATE_ADDR IPA Command: ***********************************************/
|
||||
struct qeth_create_destroy_address {
|
||||
__u8 unique_id[8];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* REGISTER_LOCAL_ADDR IPA Command: ***************************************/
|
||||
/* TODO: define in analogy to commands define above */
|
||||
|
||||
/* UNREGISTER_LOCAL_ADDR IPA Command: *************************************/
|
||||
/* TODO: define in analogy to commands define above */
|
||||
|
||||
/* Header for each IPA command */
|
||||
struct qeth_ipacmd_hdr {
|
||||
__u8 command;
|
||||
__u8 initiator;
|
||||
__u16 seqno;
|
||||
__u16 return_code;
|
||||
__u8 adapter_type;
|
||||
__u8 rel_adapter_no;
|
||||
__u8 prim_version_no;
|
||||
__u8 param_count;
|
||||
__u16 prot_version;
|
||||
__u32 ipa_supported;
|
||||
__u32 ipa_enabled;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/* The IPA command itself */
|
||||
struct qeth_ipa_cmd {
|
||||
struct qeth_ipacmd_hdr hdr;
|
||||
union {
|
||||
struct qeth_ipacmd_setdelip4 setdelip4;
|
||||
struct qeth_ipacmd_setdelip6 setdelip6;
|
||||
struct qeth_ipacmd_setdelipm setdelipm;
|
||||
struct qeth_ipacmd_setassparms setassparms;
|
||||
struct qeth_ipacmd_layer2setdelmac setdelmac;
|
||||
struct qeth_ipacmd_layer2setdelvlan setdelvlan;
|
||||
struct qeth_create_destroy_address create_destroy_addr;
|
||||
struct qeth_ipacmd_setadpparms setadapterparms;
|
||||
struct qeth_set_routing setrtg;
|
||||
} data;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
/*
|
||||
* special command for ARP processing.
|
||||
* this is not included in setassparms command before, because we get
|
||||
* problem with the size of struct qeth_ipacmd_setassparms otherwise
|
||||
*/
|
||||
enum qeth_ipa_arp_return_codes {
|
||||
QETH_IPA_ARP_RC_SUCCESS = 0x0000,
|
||||
QETH_IPA_ARP_RC_FAILED = 0x0001,
|
||||
QETH_IPA_ARP_RC_NOTSUPP = 0x0002,
|
||||
QETH_IPA_ARP_RC_OUT_OF_RANGE = 0x0003,
|
||||
QETH_IPA_ARP_RC_Q_NOTSUPP = 0x0004,
|
||||
QETH_IPA_ARP_RC_Q_NO_DATA = 0x0008,
|
||||
};
|
||||
|
||||
|
||||
extern char *
|
||||
qeth_get_ipa_msg(enum qeth_ipa_return_codes rc);
|
||||
extern char *
|
||||
qeth_get_ipa_cmd_name(enum qeth_ipa_cmds cmd);
|
||||
|
||||
#define QETH_SETASS_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
|
||||
sizeof(struct qeth_ipacmd_setassparms_hdr))
|
||||
#define QETH_IPA_ARP_DATA_POS(buffer) (buffer + IPA_PDU_HEADER_SIZE + \
|
||||
QETH_SETASS_BASE_LEN)
|
||||
#define QETH_SETADP_BASE_LEN (sizeof(struct qeth_ipacmd_hdr) + \
|
||||
sizeof(struct qeth_ipacmd_setadpparms_hdr))
|
||||
#define QETH_SNMP_SETADP_CMDLENGTH 16
|
||||
|
||||
#define QETH_ARP_DATA_SIZE 3968
|
||||
#define QETH_ARP_CMD_LEN (QETH_ARP_DATA_SIZE + 8)
|
||||
/* Helper functions */
|
||||
#define IS_IPA_REPLY(cmd) ((cmd->hdr.initiator == IPA_CMD_INITIATOR_HOST) || \
|
||||
(cmd->hdr.initiator == IPA_CMD_INITIATOR_OSA_REPLY))
|
||||
|
||||
/*****************************************************************************/
|
||||
/* END OF IP Assist related definitions */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
extern unsigned char WRITE_CCW[];
|
||||
extern unsigned char READ_CCW[];
|
||||
|
||||
extern unsigned char CM_ENABLE[];
|
||||
#define CM_ENABLE_SIZE 0x63
|
||||
#define QETH_CM_ENABLE_ISSUER_RM_TOKEN(buffer) (buffer+0x2c)
|
||||
#define QETH_CM_ENABLE_FILTER_TOKEN(buffer) (buffer+0x53)
|
||||
#define QETH_CM_ENABLE_USER_DATA(buffer) (buffer+0x5b)
|
||||
|
||||
#define QETH_CM_ENABLE_RESP_FILTER_TOKEN(buffer) \
|
||||
(PDU_ENCAPSULATION(buffer)+ 0x13)
|
||||
|
||||
|
||||
extern unsigned char CM_SETUP[];
|
||||
#define CM_SETUP_SIZE 0x64
|
||||
#define QETH_CM_SETUP_DEST_ADDR(buffer) (buffer+0x2c)
|
||||
#define QETH_CM_SETUP_CONNECTION_TOKEN(buffer) (buffer+0x51)
|
||||
#define QETH_CM_SETUP_FILTER_TOKEN(buffer) (buffer+0x5a)
|
||||
|
||||
#define QETH_CM_SETUP_RESP_DEST_ADDR(buffer) \
|
||||
(PDU_ENCAPSULATION(buffer) + 0x1a)
|
||||
|
||||
extern unsigned char ULP_ENABLE[];
|
||||
#define ULP_ENABLE_SIZE 0x6b
|
||||
#define QETH_ULP_ENABLE_LINKNUM(buffer) (buffer+0x61)
|
||||
#define QETH_ULP_ENABLE_DEST_ADDR(buffer) (buffer+0x2c)
|
||||
#define QETH_ULP_ENABLE_FILTER_TOKEN(buffer) (buffer+0x53)
|
||||
#define QETH_ULP_ENABLE_PORTNAME_AND_LL(buffer) (buffer+0x62)
|
||||
#define QETH_ULP_ENABLE_RESP_FILTER_TOKEN(buffer) \
|
||||
(PDU_ENCAPSULATION(buffer) + 0x13)
|
||||
#define QETH_ULP_ENABLE_RESP_MAX_MTU(buffer) \
|
||||
(PDU_ENCAPSULATION(buffer)+ 0x1f)
|
||||
#define QETH_ULP_ENABLE_RESP_DIFINFO_LEN(buffer) \
|
||||
(PDU_ENCAPSULATION(buffer) + 0x17)
|
||||
#define QETH_ULP_ENABLE_RESP_LINK_TYPE(buffer) \
|
||||
(PDU_ENCAPSULATION(buffer)+ 0x2b)
|
||||
/* Layer 2 defintions */
|
||||
#define QETH_PROT_LAYER2 0x08
|
||||
#define QETH_PROT_TCPIP 0x03
|
||||
#define QETH_PROT_OSN2 0x0a
|
||||
#define QETH_ULP_ENABLE_PROT_TYPE(buffer) (buffer+0x50)
|
||||
#define QETH_IPA_CMD_PROT_TYPE(buffer) (buffer+0x19)
|
||||
|
||||
extern unsigned char ULP_SETUP[];
|
||||
#define ULP_SETUP_SIZE 0x6c
|
||||
#define QETH_ULP_SETUP_DEST_ADDR(buffer) (buffer+0x2c)
|
||||
#define QETH_ULP_SETUP_CONNECTION_TOKEN(buffer) (buffer+0x51)
|
||||
#define QETH_ULP_SETUP_FILTER_TOKEN(buffer) (buffer+0x5a)
|
||||
#define QETH_ULP_SETUP_CUA(buffer) (buffer+0x68)
|
||||
#define QETH_ULP_SETUP_REAL_DEVADDR(buffer) (buffer+0x6a)
|
||||
|
||||
#define QETH_ULP_SETUP_RESP_CONNECTION_TOKEN(buffer) \
|
||||
(PDU_ENCAPSULATION(buffer)+0x1a)
|
||||
|
||||
|
||||
extern unsigned char DM_ACT[];
|
||||
#define DM_ACT_SIZE 0x55
|
||||
#define QETH_DM_ACT_DEST_ADDR(buffer) (buffer+0x2c)
|
||||
#define QETH_DM_ACT_CONNECTION_TOKEN(buffer) (buffer+0x51)
|
||||
|
||||
|
||||
|
||||
#define QETH_TRANSPORT_HEADER_SEQ_NO(buffer) (buffer+4)
|
||||
#define QETH_PDU_HEADER_SEQ_NO(buffer) (buffer+0x1c)
|
||||
#define QETH_PDU_HEADER_ACK_SEQ_NO(buffer) (buffer+0x20)
|
||||
|
||||
extern unsigned char IDX_ACTIVATE_READ[];
|
||||
extern unsigned char IDX_ACTIVATE_WRITE[];
|
||||
|
||||
#define IDX_ACTIVATE_SIZE 0x22
|
||||
#define QETH_IDX_ACT_ISSUER_RM_TOKEN(buffer) (buffer+0x0c)
|
||||
#define QETH_IDX_NO_PORTNAME_REQUIRED(buffer) ((buffer)[0x0b]&0x80)
|
||||
#define QETH_IDX_ACT_FUNC_LEVEL(buffer) (buffer+0x10)
|
||||
#define QETH_IDX_ACT_DATASET_NAME(buffer) (buffer+0x16)
|
||||
#define QETH_IDX_ACT_QDIO_DEV_CUA(buffer) (buffer+0x1e)
|
||||
#define QETH_IDX_ACT_QDIO_DEV_REALADDR(buffer) (buffer+0x20)
|
||||
#define QETH_IS_IDX_ACT_POS_REPLY(buffer) (((buffer)[0x08]&3)==2)
|
||||
#define QETH_IDX_REPLY_LEVEL(buffer) (buffer+0x12)
|
||||
#define QETH_IDX_ACT_CAUSE_CODE(buffer) (buffer)[0x09]
|
||||
|
||||
#define PDU_ENCAPSULATION(buffer) \
|
||||
(buffer + *(buffer + (*(buffer+0x0b)) + \
|
||||
*(buffer + *(buffer+0x0b)+0x11) +0x07))
|
||||
|
||||
#define IS_IPA(buffer) \
|
||||
((buffer) && \
|
||||
( *(buffer + ((*(buffer+0x0b))+4) )==0xc1) )
|
||||
|
||||
#define ADDR_FRAME_TYPE_DIX 1
|
||||
#define ADDR_FRAME_TYPE_802_3 2
|
||||
#define ADDR_FRAME_TYPE_TR_WITHOUT_SR 0x10
|
||||
#define ADDR_FRAME_TYPE_TR_WITH_SR 0x20
|
||||
|
||||
#endif
|
|
@ -1,316 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* linux/drivers/s390/net/qeth_fs.c
|
||||
*
|
||||
* Linux on zSeries OSA Express and HiperSockets support
|
||||
* This file contains code related to procfs.
|
||||
*
|
||||
* Copyright 2000,2003 IBM Corporation
|
||||
*
|
||||
* Author(s): Thomas Spatzier <tspat@de.ibm.com>
|
||||
*
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/proc_fs.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/rwsem.h>
|
||||
|
||||
#include "qeth.h"
|
||||
#include "qeth_mpc.h"
|
||||
#include "qeth_fs.h"
|
||||
|
||||
/***** /proc/qeth *****/
|
||||
#define QETH_PROCFILE_NAME "qeth"
|
||||
static struct proc_dir_entry *qeth_procfile;
|
||||
|
||||
static int
|
||||
qeth_procfile_seq_match(struct device *dev, void *data)
|
||||
{
|
||||
return(dev ? 1 : 0);
|
||||
}
|
||||
|
||||
static void *
|
||||
qeth_procfile_seq_start(struct seq_file *s, loff_t *offset)
|
||||
{
|
||||
struct device *dev = NULL;
|
||||
loff_t nr = 0;
|
||||
|
||||
if (*offset == 0)
|
||||
return SEQ_START_TOKEN;
|
||||
while (1) {
|
||||
dev = driver_find_device(&qeth_ccwgroup_driver.driver, dev,
|
||||
NULL, qeth_procfile_seq_match);
|
||||
if (++nr == *offset)
|
||||
break;
|
||||
put_device(dev);
|
||||
}
|
||||
return dev;
|
||||
}
|
||||
|
||||
static void
|
||||
qeth_procfile_seq_stop(struct seq_file *s, void* it)
|
||||
{
|
||||
}
|
||||
|
||||
static void *
|
||||
qeth_procfile_seq_next(struct seq_file *s, void *it, loff_t *offset)
|
||||
{
|
||||
struct device *prev, *next;
|
||||
|
||||
if (it == SEQ_START_TOKEN)
|
||||
prev = NULL;
|
||||
else
|
||||
prev = (struct device *) it;
|
||||
next = driver_find_device(&qeth_ccwgroup_driver.driver,
|
||||
prev, NULL, qeth_procfile_seq_match);
|
||||
(*offset)++;
|
||||
return (void *) next;
|
||||
}
|
||||
|
||||
static inline const char *
|
||||
qeth_get_router_str(struct qeth_card *card, int ipv)
|
||||
{
|
||||
enum qeth_routing_types routing_type = NO_ROUTER;
|
||||
|
||||
if (ipv == 4) {
|
||||
routing_type = card->options.route4.type;
|
||||
} else {
|
||||
#ifdef CONFIG_QETH_IPV6
|
||||
routing_type = card->options.route6.type;
|
||||
#else
|
||||
return "n/a";
|
||||
#endif /* CONFIG_QETH_IPV6 */
|
||||
}
|
||||
|
||||
switch (routing_type){
|
||||
case PRIMARY_ROUTER:
|
||||
return "pri";
|
||||
case SECONDARY_ROUTER:
|
||||
return "sec";
|
||||
case MULTICAST_ROUTER:
|
||||
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
|
||||
return "mc+";
|
||||
return "mc";
|
||||
case PRIMARY_CONNECTOR:
|
||||
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
|
||||
return "p+c";
|
||||
return "p.c";
|
||||
case SECONDARY_CONNECTOR:
|
||||
if (card->info.broadcast_capable == QETH_BROADCAST_WITHOUT_ECHO)
|
||||
return "s+c";
|
||||
return "s.c";
|
||||
default: /* NO_ROUTER */
|
||||
return "no";
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
qeth_procfile_seq_show(struct seq_file *s, void *it)
|
||||
{
|
||||
struct device *device;
|
||||
struct qeth_card *card;
|
||||
char tmp[12]; /* for qeth_get_prioq_str */
|
||||
|
||||
if (it == SEQ_START_TOKEN){
|
||||
seq_printf(s, "devices CHPID interface "
|
||||
"cardtype port chksum prio-q'ing rtr4 "
|
||||
"rtr6 fsz cnt\n");
|
||||
seq_printf(s, "-------------------------- ----- ---------- "
|
||||
"-------------- ---- ------ ---------- ---- "
|
||||
"---- ----- -----\n");
|
||||
} else {
|
||||
device = (struct device *) it;
|
||||
card = device->driver_data;
|
||||
seq_printf(s, "%s/%s/%s x%02X %-10s %-14s %-4i ",
|
||||
CARD_RDEV_ID(card),
|
||||
CARD_WDEV_ID(card),
|
||||
CARD_DDEV_ID(card),
|
||||
card->info.chpid,
|
||||
QETH_CARD_IFNAME(card),
|
||||
qeth_get_cardname_short(card),
|
||||
card->info.portno);
|
||||
if (card->lan_online)
|
||||
seq_printf(s, "%-6s %-10s %-4s %-4s %-5s %-5i\n",
|
||||
qeth_get_checksum_str(card),
|
||||
qeth_get_prioq_str(card, tmp),
|
||||
qeth_get_router_str(card, 4),
|
||||
qeth_get_router_str(card, 6),
|
||||
qeth_get_bufsize_str(card),
|
||||
card->qdio.in_buf_pool.buf_count);
|
||||
else
|
||||
seq_printf(s, " +++ LAN OFFLINE +++\n");
|
||||
put_device(device);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations qeth_procfile_seq_ops = {
|
||||
.start = qeth_procfile_seq_start,
|
||||
.stop = qeth_procfile_seq_stop,
|
||||
.next = qeth_procfile_seq_next,
|
||||
.show = qeth_procfile_seq_show,
|
||||
};
|
||||
|
||||
static int
|
||||
qeth_procfile_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &qeth_procfile_seq_ops);
|
||||
}
|
||||
|
||||
static const struct file_operations qeth_procfile_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = qeth_procfile_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
/***** /proc/qeth_perf *****/
|
||||
#define QETH_PERF_PROCFILE_NAME "qeth_perf"
|
||||
static struct proc_dir_entry *qeth_perf_procfile;
|
||||
|
||||
static int
|
||||
qeth_perf_procfile_seq_show(struct seq_file *s, void *it)
|
||||
{
|
||||
struct device *device;
|
||||
struct qeth_card *card;
|
||||
|
||||
|
||||
if (it == SEQ_START_TOKEN)
|
||||
return 0;
|
||||
|
||||
device = (struct device *) it;
|
||||
card = device->driver_data;
|
||||
seq_printf(s, "For card with devnos %s/%s/%s (%s):\n",
|
||||
CARD_RDEV_ID(card),
|
||||
CARD_WDEV_ID(card),
|
||||
CARD_DDEV_ID(card),
|
||||
QETH_CARD_IFNAME(card)
|
||||
);
|
||||
if (!card->options.performance_stats)
|
||||
seq_printf(s, "Performance statistics are deactivated.\n");
|
||||
seq_printf(s, " Skb's/buffers received : %lu/%u\n"
|
||||
" Skb's/buffers sent : %lu/%u\n\n",
|
||||
card->stats.rx_packets -
|
||||
card->perf_stats.initial_rx_packets,
|
||||
card->perf_stats.bufs_rec,
|
||||
card->stats.tx_packets -
|
||||
card->perf_stats.initial_tx_packets,
|
||||
card->perf_stats.bufs_sent
|
||||
);
|
||||
seq_printf(s, " Skb's/buffers sent without packing : %lu/%u\n"
|
||||
" Skb's/buffers sent with packing : %u/%u\n\n",
|
||||
card->stats.tx_packets - card->perf_stats.initial_tx_packets
|
||||
- card->perf_stats.skbs_sent_pack,
|
||||
card->perf_stats.bufs_sent - card->perf_stats.bufs_sent_pack,
|
||||
card->perf_stats.skbs_sent_pack,
|
||||
card->perf_stats.bufs_sent_pack
|
||||
);
|
||||
seq_printf(s, " Skbs sent in SG mode : %u\n"
|
||||
" Skb fragments sent in SG mode : %u\n\n",
|
||||
card->perf_stats.sg_skbs_sent,
|
||||
card->perf_stats.sg_frags_sent);
|
||||
seq_printf(s, " Skbs received in SG mode : %u\n"
|
||||
" Skb fragments received in SG mode : %u\n"
|
||||
" Page allocations for rx SG mode : %u\n\n",
|
||||
card->perf_stats.sg_skbs_rx,
|
||||
card->perf_stats.sg_frags_rx,
|
||||
card->perf_stats.sg_alloc_page_rx);
|
||||
seq_printf(s, " large_send tx (in Kbytes) : %u\n"
|
||||
" large_send count : %u\n\n",
|
||||
card->perf_stats.large_send_bytes >> 10,
|
||||
card->perf_stats.large_send_cnt);
|
||||
seq_printf(s, " Packing state changes no pkg.->packing : %u/%u\n"
|
||||
" Watermarks L/H : %i/%i\n"
|
||||
" Current buffer usage (outbound q's) : "
|
||||
"%i/%i/%i/%i\n\n",
|
||||
card->perf_stats.sc_dp_p, card->perf_stats.sc_p_dp,
|
||||
QETH_LOW_WATERMARK_PACK, QETH_HIGH_WATERMARK_PACK,
|
||||
atomic_read(&card->qdio.out_qs[0]->used_buffers),
|
||||
(card->qdio.no_out_queues > 1)?
|
||||
atomic_read(&card->qdio.out_qs[1]->used_buffers)
|
||||
: 0,
|
||||
(card->qdio.no_out_queues > 2)?
|
||||
atomic_read(&card->qdio.out_qs[2]->used_buffers)
|
||||
: 0,
|
||||
(card->qdio.no_out_queues > 3)?
|
||||
atomic_read(&card->qdio.out_qs[3]->used_buffers)
|
||||
: 0
|
||||
);
|
||||
seq_printf(s, " Inbound handler time (in us) : %u\n"
|
||||
" Inbound handler count : %u\n"
|
||||
" Inbound do_QDIO time (in us) : %u\n"
|
||||
" Inbound do_QDIO count : %u\n\n"
|
||||
" Outbound handler time (in us) : %u\n"
|
||||
" Outbound handler count : %u\n\n"
|
||||
" Outbound time (in us, incl QDIO) : %u\n"
|
||||
" Outbound count : %u\n"
|
||||
" Outbound do_QDIO time (in us) : %u\n"
|
||||
" Outbound do_QDIO count : %u\n\n",
|
||||
card->perf_stats.inbound_time,
|
||||
card->perf_stats.inbound_cnt,
|
||||
card->perf_stats.inbound_do_qdio_time,
|
||||
card->perf_stats.inbound_do_qdio_cnt,
|
||||
card->perf_stats.outbound_handler_time,
|
||||
card->perf_stats.outbound_handler_cnt,
|
||||
card->perf_stats.outbound_time,
|
||||
card->perf_stats.outbound_cnt,
|
||||
card->perf_stats.outbound_do_qdio_time,
|
||||
card->perf_stats.outbound_do_qdio_cnt
|
||||
);
|
||||
put_device(device);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct seq_operations qeth_perf_procfile_seq_ops = {
|
||||
.start = qeth_procfile_seq_start,
|
||||
.stop = qeth_procfile_seq_stop,
|
||||
.next = qeth_procfile_seq_next,
|
||||
.show = qeth_perf_procfile_seq_show,
|
||||
};
|
||||
|
||||
static int
|
||||
qeth_perf_procfile_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return seq_open(file, &qeth_perf_procfile_seq_ops);
|
||||
}
|
||||
|
||||
static const struct file_operations qeth_perf_procfile_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = qeth_perf_procfile_open,
|
||||
.read = seq_read,
|
||||
.llseek = seq_lseek,
|
||||
.release = seq_release,
|
||||
};
|
||||
|
||||
int __init
|
||||
qeth_create_procfs_entries(void)
|
||||
{
|
||||
qeth_procfile = create_proc_entry(QETH_PROCFILE_NAME,
|
||||
S_IFREG | 0444, NULL);
|
||||
if (qeth_procfile)
|
||||
qeth_procfile->proc_fops = &qeth_procfile_fops;
|
||||
|
||||
qeth_perf_procfile = create_proc_entry(QETH_PERF_PROCFILE_NAME,
|
||||
S_IFREG | 0444, NULL);
|
||||
if (qeth_perf_procfile)
|
||||
qeth_perf_procfile->proc_fops = &qeth_perf_procfile_fops;
|
||||
|
||||
if (qeth_procfile &&
|
||||
qeth_perf_procfile)
|
||||
return 0;
|
||||
else
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
void __exit
|
||||
qeth_remove_procfs_entries(void)
|
||||
{
|
||||
if (qeth_procfile)
|
||||
remove_proc_entry(QETH_PROCFILE_NAME, NULL);
|
||||
if (qeth_perf_procfile)
|
||||
remove_proc_entry(QETH_PERF_PROCFILE_NAME, NULL);
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load diff
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* linux/drivers/s390/net/qeth_tso.h
|
||||
*
|
||||
* Header file for qeth TCP Segmentation Offload support.
|
||||
*
|
||||
* Copyright 2004 IBM Corporation
|
||||
*
|
||||
* Author(s): Frank Pavlic <fpavlic@de.ibm.com>
|
||||
*
|
||||
*/
|
||||
#ifndef __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"
|
||||
|
||||
|
||||
static inline struct qeth_hdr_tso *
|
||||
qeth_tso_prepare_skb(struct qeth_card *card, struct sk_buff **skb)
|
||||
{
|
||||
QETH_DBF_TEXT(trace, 5, "tsoprsk");
|
||||
return qeth_push_skb(card, *skb, sizeof(struct qeth_hdr_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 = ip_hdr(skb);
|
||||
tcph = tcp_hdr(skb);
|
||||
/*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)->gso_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 = ip_hdr(skb);
|
||||
struct ipv6hdr *ip6h = ipv6_hdr(skb);
|
||||
struct tcphdr *tcph = tcp_hdr(skb);
|
||||
|
||||
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
|
||||
qeth_tso_prepare_packet(struct qeth_card *card, struct sk_buff *skb,
|
||||
int ipv, int cast_type)
|
||||
{
|
||||
struct qeth_hdr_tso *hdr;
|
||||
|
||||
QETH_DBF_TEXT(trace, 5, "tsoprep");
|
||||
|
||||
hdr = (struct qeth_hdr_tso *) qeth_tso_prepare_skb(card, &skb);
|
||||
if (hdr == NULL) {
|
||||
QETH_DBF_TEXT(trace, 4, "tsoperr");
|
||||
return -ENOMEM;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
*next_element_to_fill = element;
|
||||
}
|
||||
#endif /* __QETH_TSO_H__ */
|
Loading…
Reference in a new issue