Commit 983f27d3 authored by Jeff Garzik's avatar Jeff Garzik

Merge branch 'upstream-fixes' into upstream

Conflicts:

	drivers/s390/net/ctctty.c
parents de1e938e e82b0f2c
......@@ -20,7 +20,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/err.h>
......@@ -77,7 +77,7 @@ group_write(struct device_driver *drv, const char *buf, size_t count)
int len;
if (!(end = strchr(start, delim[i])))
return count;
return -EINVAL;
len = min_t(ptrdiff_t, BUS_ID_SIZE, end - start + 1);
strlcpy (bus_ids[i], start, len);
argv[i] = bus_ids[i];
......
......@@ -28,7 +28,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/* #define DEBUG */
#include <linux/module.h>
......@@ -297,7 +297,7 @@ MODULE_LICENSE("GPL");
/*
* Debugging stuff
*******************************************************************************/
#ifdef DEBUG
static int debuglevel = 0;
......@@ -344,7 +344,7 @@ do { \
/*
* Internal functions
*******************************************************************************/
/**
* print start banner
*/
......
......@@ -68,6 +68,7 @@ static void lcs_tasklet(unsigned long);
static void lcs_start_kernel_thread(struct lcs_card *card);
static void lcs_get_frames_cb(struct lcs_channel *, struct lcs_buffer *);
static int lcs_send_delipm(struct lcs_card *, struct lcs_ipm_list *);
static int lcs_recovery(void *ptr);
/**
* Debug Facility Stuff
......@@ -429,12 +430,6 @@ lcs_setup_card(struct lcs_card *card)
card->tx_buffer = NULL;
card->tx_emitted = 0;
/* Initialize kernel thread task used for LGW commands. */
INIT_WORK(&card->kernel_thread_starter,
(void *)lcs_start_kernel_thread,card);
card->thread_start_mask = 0;
card->thread_allowed_mask = 0;
card->thread_running_mask = 0;
init_waitqueue_head(&card->wait_q);
spin_lock_init(&card->lock);
spin_lock_init(&card->ipm_lock);
......@@ -675,8 +670,9 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
int index, rc;
LCS_DBF_TEXT(5, trace, "rdybuff");
BUG_ON(buffer->state != BUF_STATE_LOCKED &&
buffer->state != BUF_STATE_PROCESSED);
if (buffer->state != BUF_STATE_LOCKED &&
buffer->state != BUF_STATE_PROCESSED)
BUG();
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
buffer->state = BUF_STATE_READY;
index = buffer - channel->iob;
......@@ -700,7 +696,8 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
int index, prev, next;
LCS_DBF_TEXT(5, trace, "prcsbuff");
BUG_ON(buffer->state != BUF_STATE_READY);
if (buffer->state != BUF_STATE_READY)
BUG();
buffer->state = BUF_STATE_PROCESSED;
index = buffer - channel->iob;
prev = (index - 1) & (LCS_NUM_BUFFS - 1);
......@@ -732,8 +729,9 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
unsigned long flags;
LCS_DBF_TEXT(5, trace, "relbuff");
BUG_ON(buffer->state != BUF_STATE_LOCKED &&
buffer->state != BUF_STATE_PROCESSED);
if (buffer->state != BUF_STATE_LOCKED &&
buffer->state != BUF_STATE_PROCESSED)
BUG();
spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
buffer->state = BUF_STATE_EMPTY;
spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
......@@ -1147,8 +1145,6 @@ lcs_fix_multicast_list(struct lcs_card *card)
list_add_tail(&ipm->list, &card->ipm_list);
}
spin_unlock_irqrestore(&card->ipm_lock, flags);
if (card->state == DEV_STATE_UP)
netif_wake_queue(card->dev);
}
/**
......@@ -1231,17 +1227,17 @@ lcs_set_mc_addresses(struct lcs_card *card, struct in_device *in4_dev)
if (ipm != NULL)
continue; /* Address already in list. */
ipm = (struct lcs_ipm_list *)
kmalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC);
kzalloc(sizeof(struct lcs_ipm_list), GFP_ATOMIC);
if (ipm == NULL) {
PRINT_INFO("Not enough memory to add "
"new multicast entry!\n");
break;
}
memset(ipm, 0, sizeof(struct lcs_ipm_list));
memcpy(&ipm->ipm.mac_addr, buf, LCS_MAC_LENGTH);
ipm->ipm.ip_addr = im4->multiaddr;
ipm->ipm_state = LCS_IPM_STATE_SET_REQUIRED;
spin_lock_irqsave(&card->ipm_lock, flags);
LCS_DBF_HEX(2,trace,&ipm->ipm.ip_addr,4);
list_add(&ipm->list, &card->ipm_list);
spin_unlock_irqrestore(&card->ipm_lock, flags);
}
......@@ -1269,7 +1265,15 @@ lcs_register_mc_addresses(void *data)
read_unlock(&in4_dev->mc_list_lock);
in_dev_put(in4_dev);
netif_carrier_off(card->dev);
netif_tx_disable(card->dev);
wait_event(card->write.wait_q,
(card->write.state != CH_STATE_RUNNING));
lcs_fix_multicast_list(card);
if (card->state == DEV_STATE_UP) {
netif_carrier_on(card->dev);
netif_wake_queue(card->dev);
}
out:
lcs_clear_thread_running_bit(card, LCS_SET_MC_THREAD);
return 0;
......@@ -1318,6 +1322,53 @@ lcs_check_irb_error(struct ccw_device *cdev, struct irb *irb)
return PTR_ERR(irb);
}
static int
lcs_get_problem(struct ccw_device *cdev, struct irb *irb)
{
int dstat, cstat;
char *sense;
sense = (char *) irb->ecw;
cstat = irb->scsw.cstat;
dstat = irb->scsw.dstat;
if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) {
LCS_DBF_TEXT(2, trace, "CGENCHK");
return 1;
}
if (dstat & DEV_STAT_UNIT_CHECK) {
if (sense[LCS_SENSE_BYTE_1] &
LCS_SENSE_RESETTING_EVENT) {
LCS_DBF_TEXT(2, trace, "REVIND");
return 1;
}
if (sense[LCS_SENSE_BYTE_0] &
LCS_SENSE_CMD_REJECT) {
LCS_DBF_TEXT(2, trace, "CMDREJ");
return 0;
}
if ((!sense[LCS_SENSE_BYTE_0]) &&
(!sense[LCS_SENSE_BYTE_1]) &&
(!sense[LCS_SENSE_BYTE_2]) &&
(!sense[LCS_SENSE_BYTE_3])) {
LCS_DBF_TEXT(2, trace, "ZEROSEN");
return 0;
}
LCS_DBF_TEXT(2, trace, "DGENCHK");
return 1;
}
return 0;
}
void
lcs_schedule_recovery(struct lcs_card *card)
{
LCS_DBF_TEXT(2, trace, "startrec");
if (!lcs_set_thread_start_bit(card, LCS_RECOVERY_THREAD))
schedule_work(&card->kernel_thread_starter);
}
/**
* IRQ Handler for LCS channels
......@@ -1327,7 +1378,8 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
{
struct lcs_card *card;
struct lcs_channel *channel;
int index;
int rc, index;
int cstat, dstat;
if (lcs_check_irb_error(cdev, irb))
return;
......@@ -1338,10 +1390,23 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
else
channel = &card->write;
cstat = irb->scsw.cstat;
dstat = irb->scsw.dstat;
LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id);
LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.cstat, irb->scsw.dstat);
LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.fctl, irb->scsw.actl);
/* Check for channel and device errors presented */
rc = lcs_get_problem(cdev, irb);
if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) {
PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n",
cdev->dev.bus_id, dstat, cstat);
if (rc) {
lcs_schedule_recovery(card);
wake_up(&card->wait_q);
return;
}
}
/* How far in the ccw chain have we processed? */
if ((channel->state != CH_STATE_INIT) &&
(irb->scsw.fctl & SCSW_FCTL_START_FUNC)) {
......@@ -1367,7 +1432,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED)
/* CCW execution stopped on a suspend bit. */
channel->state = CH_STATE_SUSPENDED;
if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) {
if (irb->scsw.cc != 0) {
ccw_device_halt(channel->ccwdev, (addr_t) channel);
......@@ -1376,7 +1440,6 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
/* The channel has been stopped by halt_IO. */
channel->state = CH_STATE_HALTED;
}
if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) {
channel->state = CH_STATE_CLEARED;
}
......@@ -1452,7 +1515,7 @@ lcs_txbuffer_cb(struct lcs_channel *channel, struct lcs_buffer *buffer)
lcs_release_buffer(channel, buffer);
card = (struct lcs_card *)
((char *) channel - offsetof(struct lcs_card, write));
if (netif_queue_stopped(card->dev))
if (netif_queue_stopped(card->dev) && netif_carrier_ok(card->dev))
netif_wake_queue(card->dev);
spin_lock(&card->lock);
card->tx_emitted--;
......@@ -1488,6 +1551,10 @@ __lcs_start_xmit(struct lcs_card *card, struct sk_buff *skb,
card->stats.tx_carrier_errors++;
return 0;
}
if (skb->protocol == htons(ETH_P_IPV6)) {
dev_kfree_skb(skb);
return 0;
}
netif_stop_queue(card->dev);
spin_lock(&card->lock);
if (card->tx_buffer != NULL &&
......@@ -1632,30 +1699,6 @@ lcs_detect(struct lcs_card *card)
return rc;
}
/**
* reset card
*/
static int
lcs_resetcard(struct lcs_card *card)
{
int retries;
LCS_DBF_TEXT(2, trace, "rescard");
for (retries = 0; retries < 10; retries++) {
if (lcs_detect(card) == 0) {
netif_wake_queue(card->dev);
card->state = DEV_STATE_UP;
PRINT_INFO("LCS device %s successfully restarted!\n",
card->dev->name);
return 0;
}
msleep(3000);
}
PRINT_ERR("Error in Reseting LCS card!\n");
return -EIO;
}
/**
* LCS Stop card
*/
......@@ -1679,111 +1722,6 @@ lcs_stopcard(struct lcs_card *card)
return rc;
}
/**
* LGW initiated commands
*/
static int
lcs_lgw_startlan_thread(void *data)
{
struct lcs_card *card;
card = (struct lcs_card *) data;
daemonize("lgwstpln");
if (!lcs_do_run_thread(card, LCS_STARTLAN_THREAD))
return 0;
LCS_DBF_TEXT(4, trace, "lgwstpln");
if (card->dev)
netif_stop_queue(card->dev);
if (lcs_startlan(card) == 0) {
netif_wake_queue(card->dev);
card->state = DEV_STATE_UP;
PRINT_INFO("LCS Startlan for device %s succeeded!\n",
card->dev->name);
} else
PRINT_ERR("LCS Startlan for device %s failed!\n",
card->dev->name);
lcs_clear_thread_running_bit(card, LCS_STARTLAN_THREAD);
return 0;
}
/**
* Send startup command initiated by Lan Gateway
*/
static int
lcs_lgw_startup_thread(void *data)
{
int rc;
struct lcs_card *card;
card = (struct lcs_card *) data;
daemonize("lgwstaln");
if (!lcs_do_run_thread(card, LCS_STARTUP_THREAD))
return 0;
LCS_DBF_TEXT(4, trace, "lgwstaln");
if (card->dev)
netif_stop_queue(card->dev);
rc = lcs_send_startup(card, LCS_INITIATOR_LGW);
if (rc != 0) {
PRINT_ERR("Startup for LCS device %s initiated " \
"by LGW failed!\nReseting card ...\n",
card->dev->name);
/* do a card reset */
rc = lcs_resetcard(card);
if (rc == 0)
goto Done;
}
rc = lcs_startlan(card);
if (rc == 0) {
netif_wake_queue(card->dev);
card->state = DEV_STATE_UP;
}
Done:
if (rc == 0)
PRINT_INFO("LCS Startup for device %s succeeded!\n",
card->dev->name);
else
PRINT_ERR("LCS Startup for device %s failed!\n",
card->dev->name);
lcs_clear_thread_running_bit(card, LCS_STARTUP_THREAD);
return 0;
}
/**
* send stoplan command initiated by Lan Gateway
*/
static int
lcs_lgw_stoplan_thread(void *data)
{
struct lcs_card *card;
int rc;
card = (struct lcs_card *) data;
daemonize("lgwstop");
if (!lcs_do_run_thread(card, LCS_STOPLAN_THREAD))
return 0;
LCS_DBF_TEXT(4, trace, "lgwstop");
if (card->dev)
netif_stop_queue(card->dev);
if (lcs_send_stoplan(card, LCS_INITIATOR_LGW) == 0)
PRINT_INFO("Stoplan for %s initiated by LGW succeeded!\n",
card->dev->name);
else
PRINT_ERR("Stoplan %s initiated by LGW failed!\n",
card->dev->name);
/*Try to reset the card, stop it on failure */
rc = lcs_resetcard(card);
if (rc != 0)
rc = lcs_stopcard(card);
lcs_clear_thread_running_bit(card, LCS_STOPLAN_THREAD);
return rc;
}
/**
* Kernel Thread helper functions for LGW initiated commands
*/
......@@ -1791,15 +1729,12 @@ static void
lcs_start_kernel_thread(struct lcs_card *card)
{
LCS_DBF_TEXT(5, trace, "krnthrd");
if (lcs_do_start_thread(card, LCS_STARTUP_THREAD))
kernel_thread(lcs_lgw_startup_thread, (void *) card, SIGCHLD);
if (lcs_do_start_thread(card, LCS_STARTLAN_THREAD))
kernel_thread(lcs_lgw_startlan_thread, (void *) card, SIGCHLD);
if (lcs_do_start_thread(card, LCS_STOPLAN_THREAD))
kernel_thread(lcs_lgw_stoplan_thread, (void *) card, SIGCHLD);
if (lcs_do_start_thread(card, LCS_RECOVERY_THREAD))
kernel_thread(lcs_recovery, (void *) card, SIGCHLD);
#ifdef CONFIG_IP_MULTICAST
if (lcs_do_start_thread(card, LCS_SET_MC_THREAD))
kernel_thread(lcs_register_mc_addresses, (void *) card, SIGCHLD);
kernel_thread(lcs_register_mc_addresses,
(void *) card, SIGCHLD);
#endif
}
......@@ -1813,19 +1748,14 @@ lcs_get_control(struct lcs_card *card, struct lcs_cmd *cmd)
if (cmd->initiator == LCS_INITIATOR_LGW) {
switch(cmd->cmd_code) {
case LCS_CMD_STARTUP:
if (!lcs_set_thread_start_bit(card,
LCS_STARTUP_THREAD))
schedule_work(&card->kernel_thread_starter);
break;
case LCS_CMD_STARTLAN:
if (!lcs_set_thread_start_bit(card,
LCS_STARTLAN_THREAD))
schedule_work(&card->kernel_thread_starter);
lcs_schedule_recovery(card);
break;
case LCS_CMD_STOPLAN:
if (!lcs_set_thread_start_bit(card,
LCS_STOPLAN_THREAD))
schedule_work(&card->kernel_thread_starter);
PRINT_WARN("Stoplan for %s initiated by LGW.\n",
card->dev->name);
if (card->dev)
netif_carrier_off(card->dev);
break;
default:
PRINT_INFO("UNRECOGNIZED LGW COMMAND\n");
......@@ -1941,8 +1871,11 @@ lcs_stop_device(struct net_device *dev)
LCS_DBF_TEXT(2, trace, "stopdev");
card = (struct lcs_card *) dev->priv;
netif_stop_queue(dev);
netif_carrier_off(dev);
netif_tx_disable(dev);
dev->flags &= ~IFF_UP;
wait_event(card->write.wait_q,
(card->write.state != CH_STATE_RUNNING));
rc = lcs_stopcard(card);
if (rc)
PRINT_ERR("Try it again!\n ");
......@@ -1968,6 +1901,7 @@ lcs_open_device(struct net_device *dev)
} else {
dev->flags |= IFF_UP;
netif_carrier_on(dev);
netif_wake_queue(dev);
card->state = DEV_STATE_UP;
}
......@@ -2059,10 +1993,31 @@ lcs_timeout_store (struct device *dev, struct device_attribute *attr, const char
DEVICE_ATTR(lancmd_timeout, 0644, lcs_timeout_show, lcs_timeout_store);
static ssize_t
lcs_dev_recover_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct lcs_card *card = dev->driver_data;
char *tmp;
int i;
if (!card)
return -EINVAL;
if (card->state != DEV_STATE_UP)
return -EPERM;
i = simple_strtoul(buf, &tmp, 16);
if (i == 1)
lcs_schedule_recovery(card);
return count;
}
static DEVICE_ATTR(recover, 0200, NULL, lcs_dev_recover_store);
static struct attribute * lcs_attrs[] = {
&dev_attr_portno.attr,
&dev_attr_type.attr,
&dev_attr_lancmd_timeout.attr,
&dev_attr_recover.attr,
NULL,
};
......@@ -2099,6 +2054,12 @@ lcs_probe_device(struct ccwgroup_device *ccwgdev)
ccwgdev->dev.driver_data = card;
ccwgdev->cdev[0]->handler = lcs_irq;
ccwgdev->cdev[1]->handler = lcs_irq;
card->gdev = ccwgdev;
INIT_WORK(&card->kernel_thread_starter,
(void *) lcs_start_kernel_thread, card);
card->thread_start_mask = 0;
card->thread_allowed_mask = 0;
card->thread_running_mask = 0;
return 0;
}
......@@ -2200,6 +2161,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
if (recover_state == DEV_STATE_RECOVER) {
lcs_set_multicast_list(card->dev);
card->dev->flags |= IFF_UP;
netif_carrier_on(card->dev);
netif_wake_queue(card->dev);
card->state = DEV_STATE_UP;
} else {
......@@ -2229,7 +2191,7 @@ lcs_new_device(struct ccwgroup_device *ccwgdev)
* lcs_shutdown_device, called when setting the group device offline.
*/
static int
lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
__lcs_shutdown_device(struct ccwgroup_device *ccwgdev, int recovery_mode)
{
struct lcs_card *card;
enum lcs_dev_states recover_state;
......@@ -2239,9 +2201,11 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
card = (struct lcs_card *)ccwgdev->dev.driver_data;
if (!card)
return -ENODEV;
if (recovery_mode == 0) {
lcs_set_allowed_threads(card, 0);
if (lcs_wait_for_threads(card, LCS_SET_MC_THREAD))
return -ERESTARTSYS;
}
LCS_DBF_HEX(3, setup, &card, sizeof(void*));
recover_state = card->state;
......@@ -2256,6 +2220,43 @@ lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
return 0;
}
static int
lcs_shutdown_device(struct ccwgroup_device *ccwgdev)
{
return __lcs_shutdown_device(ccwgdev, 0);
}
/**
* drive lcs recovery after startup and startlan initiated by Lan Gateway
*/
static int
lcs_recovery(void *ptr)
{
struct lcs_card *card;
struct ccwgroup_device *gdev;
int rc;
card = (struct lcs_card *) ptr;
daemonize("lcs_recover");
LCS_DBF_TEXT(4, trace, "recover1");
if (!lcs_do_run_thread(card, LCS_RECOVERY_THREAD))
return 0;
LCS_DBF_TEXT(4, trace, "recover2");
gdev = card->gdev;
PRINT_WARN("Recovery of device %s started...\n", gdev->dev.bus_id);
rc = __lcs_shutdown_device(gdev, 1);
rc = lcs_new_device(gdev);
if (!rc)
PRINT_INFO("Device %s successfully recovered!\n",
card->dev->name);
else
PRINT_INFO("Device %s could not be recovered!\n",
card->dev->name);
lcs_clear_thread_running_bit(card, LCS_RECOVERY_THREAD);
return 0;
}
/**
* lcs_remove_device, free buffers and card
*/
......
......@@ -73,13 +73,17 @@ do { \
/**
* LCS sense byte definitions
*/
#define LCS_SENSE_BYTE_0 0
#define LCS_SENSE_BYTE_1 1
#define LCS_SENSE_BYTE_2 2
#define LCS_SENSE_BYTE_3 3
#define LCS_SENSE_INTERFACE_DISCONNECT 0x01
#define LCS_SENSE_EQUIPMENT_CHECK 0x10
#define LCS_SENSE_BUS_OUT_CHECK 0x20
#define LCS_SENSE_INTERVENTION_REQUIRED 0x40
#define LCS_SENSE_CMD_REJECT 0x80
#define LCS_SENSE_RESETTING_EVENT 0x0080
#define LCS_SENSE_DEVICE_ONLINE 0x0020
#define LCS_SENSE_RESETTING_EVENT 0x80
#define LCS_SENSE_DEVICE_ONLINE 0x20
/**
* LCS packet type definitions
......@@ -152,10 +156,9 @@ enum lcs_dev_states {
enum lcs_threads {
LCS_SET_MC_THREAD = 1,
LCS_STARTLAN_THREAD = 2,
LCS_STOPLAN_THREAD = 4,
LCS_STARTUP_THREAD = 8,
LCS_RECOVERY_THREAD = 2,
};
/**
* LCS struct declarations
*/
......@@ -286,6 +289,7 @@ struct lcs_card {
struct net_device_stats stats;
unsigned short (*lan_type_trans)(struct sk_buff *skb,
struct net_device *dev);
struct ccwgroup_device *gdev;
struct lcs_channel read;
struct lcs_channel write;
struct lcs_buffer *tx_buffer;
......
......@@ -30,7 +30,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#undef DEBUG
#include <linux/module.h>
......@@ -65,7 +65,7 @@ MODULE_AUTHOR
("(C) 2001 IBM Corporation by Fritz Elfert (felfert@millenux.com)");
MODULE_DESCRIPTION ("Linux for S/390 IUCV network driver");
#define PRINTK_HEADER " iucv: " /* for debugging */
static struct device_driver netiucv_driver = {
......@@ -202,7 +202,7 @@ netiucv_printname(char *name)
*p = '\0';
return tmp;
}
/**
* States of the interface statemachine.
*/
......@@ -244,7 +244,7 @@ static const char *dev_event_names[] = {
"Connection up",
"Connection down",
};
/**
* Events of the connection statemachine
*/
......@@ -364,7 +364,7 @@ static const char *conn_state_names[] = {
"Connect error",
};
/**
* Debug Facility Stuff
*/
......@@ -516,7 +516,7 @@ static void
fsm_action_nop(fsm_instance *fi, int event, void *arg)
{
}
/**
* Actions of the connection statemachine
*****************************************************************************/
......@@ -993,7 +993,7 @@ static const fsm_node conn_fsm[] = {
static const int CONN_FSM_LEN = sizeof(conn_fsm) / sizeof(fsm_node);
/**
* Actions for interface - statemachine.
*****************************************************************************/
......@@ -1220,7 +1220,7 @@ netiucv_transmit_skb(struct iucv_connection *conn, struct sk_buff *skb) {
return rc;
}
/**
* Interface API for upper network layers
*****************************************************************************/
......
......@@ -1099,7 +1099,7 @@ qeth_string_to_ipaddr4(const char *buf, __u8 *addr)
rc = sscanf(buf, "%d.%d.%d.%d%n",
&in[0], &in[1], &in[2], &in[3], &count);
if (rc != 4 || count)
if (rc != 4 || count<=0)
return -EINVAL;
for (count = 0; count < 4; count++) {
if (in[count] > 255)
......
......@@ -3798,10 +3798,10 @@ qeth_open(struct net_device *dev)
QETH_DBF_TEXT(trace,4,"nomacadr");
return -EPERM;
}
card->dev->flags |= IFF_UP;
netif_start_queue(dev);
card->data.state = CH_STATE_UP;
card->state = CARD_STATE_UP;
card->dev->flags |= IFF_UP;
netif_start_queue(dev);
if (!card->lan_online && netif_carrier_ok(dev))
netif_carrier_off(dev);
......@@ -3817,7 +3817,7 @@ qeth_stop(struct net_device *dev)
card = (struct qeth_card *) dev->priv;
netif_stop_queue(dev);
netif_tx_disable(dev);
card->dev->flags &= ~IFF_UP;
if (card->state == CARD_STATE_UP)
card->state = CARD_STATE_SOFTSETUP;
......@@ -3958,7 +3958,7 @@ qeth_prepare_skb(struct qeth_card *card, struct sk_buff **skb,
#endif
*hdr = (struct qeth_hdr *)
qeth_push_skb(card, skb, sizeof(struct qeth_hdr));
if (hdr == NULL)
if (*hdr == NULL)
return -EINVAL;
return 0;
}
......@@ -4416,6 +4416,8 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
enum qeth_large_send_types large_send = QETH_LARGE_SEND_NO;
struct qeth_eddp_context *ctx = NULL;
int tx_bytes = skb->len;
unsigned short nr_frags = skb_shinfo(skb)->nr_frags;
unsigned short tso_size = skb_shinfo(skb)->tso_size;
int rc;
QETH_DBF_TEXT(trace, 6, "sendpkt");
......@@ -4498,16 +4500,16 @@ qeth_send_packet(struct qeth_card *card, struct sk_buff *skb)
card->stats.tx_packets++;
card->stats.tx_bytes += tx_bytes;
#ifdef CONFIG_QETH_PERF_STATS
if (skb_shinfo(skb)->tso_size &&
if (tso_size &&
!(large_send == QETH_LARGE_SEND_NO)) {
card->perf_stats.large_send_bytes += skb->len;
card->perf_stats.large_send_bytes += tx_bytes;
card->perf_stats.large_send_cnt++;
}
if (skb_shinfo(skb)->nr_frags > 0){
if (nr_frags > 0){
card->perf_stats.sg_skbs_sent++;
/* nr_frags + skb->data */
card->perf_stats.sg_frags_sent +=
skb_shinfo(skb)->nr_frags + 1;
nr_frags + 1;
}
#endif /* CONFIG_QETH_PERF_STATS */
}
......@@ -6359,12 +6361,9 @@ qeth_netdev_init(struct net_device *dev)
dev->vlan_rx_kill_vid = qeth_vlan_rx_kill_vid;
dev->vlan_rx_add_vid = qeth_vlan_rx_add_vid;
#endif
dev->hard_header = card->orig_hard_header;
if (qeth_get_netdev_flags(card) & IFF_NOARP) {
dev->rebuild_header = NULL;
dev->hard_header = NULL;
if (card->options.fake_ll)
dev->hard_header = qeth_fake_header;
dev->header_cache_update = NULL;
dev->hard_header_cache = NULL;
}
......@@ -6373,6 +6372,9 @@ qeth_netdev_init(struct net_device *dev)
if (!(card->info.unique_id & UNIQUE_ID_NOT_BY_CARD))
card->dev->dev_id = card->info.unique_id & 0xffff;
#endif
if (card->options.fake_ll &&
(qeth_get_netdev_flags(card) & IFF_NOARP))
dev->hard_header = qeth_fake_header;
dev->hard_header_parse = NULL;
dev->set_mac_address = qeth_layer2_set_mac_address;
dev->flags |= qeth_get_netdev_flags(card);
......@@ -6477,6 +6479,9 @@ qeth_hardsetup_card(struct qeth_card *card)
/*network device will be recovered*/
if (card->dev) {
card->dev->hard_header = card->orig_hard_header;
if (card->options.fake_ll &&
(qeth_get_netdev_flags(card) & IFF_NOARP))
card->dev->hard_header = qeth_fake_header;
return 0;
}
/* at first set_online allocate netdev */
......@@ -7031,14 +7036,12 @@ qeth_softsetup_ipv6(struct qeth_card *card)
QETH_DBF_TEXT(trace,3,"softipv6");
netif_stop_queue(card->dev);
rc = qeth_send_startlan(card, QETH_PROT_IPV6);
if (rc) {
PRINT_ERR("IPv6 startlan failed on %s\n",
QETH_CARD_IFNAME(card));
return rc;
}
netif_wake_queue(card->dev);
rc = qeth_query_ipassists(card,QETH_PROT_IPV6);
if (rc) {
PRINT_ERR("IPv6 query ipassist failed on %s\n",
......@@ -7352,7 +7355,8 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
card->options.large_send = type;
return 0;
}
netif_stop_queue(card->dev);
if (card->state == CARD_STATE_UP)
netif_tx_disable(card->dev);
card->options.large_send = type;
switch (card->options.large_send) {
case QETH_LARGE_SEND_EDDP:
......@@ -7374,6 +7378,7 @@ qeth_set_large_send(struct qeth_card *card, enum qeth_large_send_types type)
card->dev->features &= ~(NETIF_F_TSO | NETIF_F_SG);
break;
}
if (card->state == CARD_STATE_UP)
netif_wake_queue(card->dev);
return rc;
}
......@@ -7427,7 +7432,7 @@ qeth_softsetup_card(struct qeth_card *card)
if ((rc = qeth_setrouting_v6(card)))
QETH_DBF_TEXT_(setup, 2, "5err%d", rc);
out:
netif_stop_queue(card->dev);
netif_tx_disable(card->dev);
return 0;
}
......@@ -7736,10 +7741,8 @@ static int
qeth_register_netdev(struct qeth_card *card)
{
QETH_DBF_TEXT(setup, 3, "regnetd");
if (card->dev->reg_state != NETREG_UNINITIALIZED) {
qeth_netdev_init(card->dev);
if (card->dev->reg_state != NETREG_UNINITIALIZED)
return 0;
}
/* sysfs magic */
SET_NETDEV_DEV(card->dev, &card->gdev->dev);
return register_netdev(card->dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment