|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _CTCMAIN_H_
|
|
|
|
#define _CTCMAIN_H_
|
|
|
|
|
|
|
|
#include <asm/ccwdev.h>
|
|
|
|
#include <asm/ccwgroup.h>
|
|
|
|
|
|
|
|
#include <linux/skbuff.h>
|
|
|
|
#include <linux/netdevice.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_OS390 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));
|
|
|
|
netif_wake_queue(dev);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline__ int
|
|
|
|
ctc_test_and_set_busy(struct net_device * dev)
|
|
|
|
{
|
|
|
|
netif_stop_queue(dev);
|
|
|
|
return test_and_set_bit(0, &((struct ctc_priv *) dev->priv)->tbusy);
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|