From 170b828a31bbeaee3a80a05acefe3596e38f09e0 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Mon, 4 Dec 2006 19:33:47 -0800 Subject: [ATM]: Add CPPFLAGS to byteorder.h check O= builds produced errors in the shell command because of unfound headers. Signed-off-by: Ben Collins Signed-off-by: Andrew Morton Signed-off-by: David S. Miller --- drivers/atm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/atm/Makefile b/drivers/atm/Makefile index b5077ce8cb40..1b16f8166b09 100644 --- a/drivers/atm/Makefile +++ b/drivers/atm/Makefile @@ -41,7 +41,7 @@ ifeq ($(CONFIG_ATM_FORE200E_PCA),y) # guess the target endianess to choose the right PCA-200E firmware image ifeq ($(CONFIG_ATM_FORE200E_PCA_DEFAULT_FW),y) byteorder.h := include$(if $(patsubst $(srctree),,$(objtree)),2)/asm/byteorder.h - CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2) + CONFIG_ATM_FORE200E_PCA_FW := $(obj)/pca200e$(if $(shell $(CC) $(CPPFLAGS) -E -dM $(byteorder.h) | grep ' __LITTLE_ENDIAN '),.bin,_ecd.bin2) endif endif -- cgit v1.2.1 From 9fe757b0cfcee0724027a675c533077287a21b96 Mon Sep 17 00:00:00 2001 From: Jordan Crouse Date: Wed, 4 Oct 2006 18:48:57 +1000 Subject: [PATCH] crypto: Add support for the Geode LX AES hardware Add a driver to support the AES hardware on the Geode LX processor. Signed-off-by: Jordan Crouse Signed-off-by: Herbert Xu --- drivers/crypto/Kconfig | 13 ++ drivers/crypto/Makefile | 1 + drivers/crypto/geode-aes.c | 474 +++++++++++++++++++++++++++++++++++++++++++++ drivers/crypto/geode-aes.h | 42 ++++ 4 files changed, 530 insertions(+) create mode 100644 drivers/crypto/geode-aes.c create mode 100644 drivers/crypto/geode-aes.h (limited to 'drivers') diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index adb554153f67..e816535ab305 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -51,4 +51,17 @@ config CRYPTO_DEV_PADLOCK_SHA If unsure say M. The compiled module will be called padlock-sha.ko +config CRYPTO_DEV_GEODE + tristate "Support for the Geode LX AES engine" + depends on CRYPTO && X86_32 + select CRYPTO_ALGAPI + select CRYPTO_BLKCIPHER + default m + help + Say 'Y' here to use the AMD Geode LX processor on-board AES + engine for the CryptoAPI AES alogrithm. + + To compile this driver as a module, choose M here: the module + will be called geode-aes. + endmenu diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile index 4c3d0ec1cf80..6059cf869414 100644 --- a/drivers/crypto/Makefile +++ b/drivers/crypto/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_CRYPTO_DEV_PADLOCK) += padlock.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_AES) += padlock-aes.o obj-$(CONFIG_CRYPTO_DEV_PADLOCK_SHA) += padlock-sha.o +obj-$(CONFIG_CRYPTO_DEV_GEODE) += geode-aes.o diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c new file mode 100644 index 000000000000..da2d35db8b48 --- /dev/null +++ b/drivers/crypto/geode-aes.c @@ -0,0 +1,474 @@ + /* Copyright (C) 2004-2006, Advanced Micro Devices, Inc. + * + * 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 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "geode-aes.h" + +/* Register definitions */ + +#define AES_CTRLA_REG 0x0000 + +#define AES_CTRL_START 0x01 +#define AES_CTRL_DECRYPT 0x00 +#define AES_CTRL_ENCRYPT 0x02 +#define AES_CTRL_WRKEY 0x04 +#define AES_CTRL_DCA 0x08 +#define AES_CTRL_SCA 0x10 +#define AES_CTRL_CBC 0x20 + +#define AES_INTR_REG 0x0008 + +#define AES_INTRA_PENDING (1 << 16) +#define AES_INTRB_PENDING (1 << 17) + +#define AES_INTR_PENDING (AES_INTRA_PENDING | AES_INTRB_PENDING) +#define AES_INTR_MASK 0x07 + +#define AES_SOURCEA_REG 0x0010 +#define AES_DSTA_REG 0x0014 +#define AES_LENA_REG 0x0018 +#define AES_WRITEKEY0_REG 0x0030 +#define AES_WRITEIV0_REG 0x0040 + +/* A very large counter that is used to gracefully bail out of an + * operation in case of trouble + */ + +#define AES_OP_TIMEOUT 0x50000 + +/* Static structures */ + +static void __iomem * _iobase; +static spinlock_t lock; + +/* Write a 128 bit field (either a writable key or IV) */ +static inline void +_writefield(u32 offset, void *value) +{ + int i; + for(i = 0; i < 4; i++) + iowrite32(((u32 *) value)[i], _iobase + offset + (i * 4)); +} + +/* Read a 128 bit field (either a writable key or IV) */ +static inline void +_readfield(u32 offset, void *value) +{ + int i; + for(i = 0; i < 4; i++) + ((u32 *) value)[i] = ioread32(_iobase + offset + (i * 4)); +} + +static int +do_crypt(void *src, void *dst, int len, u32 flags) +{ + u32 status; + u32 counter = AES_OP_TIMEOUT; + + iowrite32(virt_to_phys(src), _iobase + AES_SOURCEA_REG); + iowrite32(virt_to_phys(dst), _iobase + AES_DSTA_REG); + iowrite32(len, _iobase + AES_LENA_REG); + + /* Start the operation */ + iowrite32(AES_CTRL_START | flags, _iobase + AES_CTRLA_REG); + + do + status = ioread32(_iobase + AES_INTR_REG); + while(!(status & AES_INTRA_PENDING) && --counter); + + /* Clear the event */ + iowrite32((status & 0xFF) | AES_INTRA_PENDING, _iobase + AES_INTR_REG); + return counter ? 0 : 1; +} + +unsigned int +geode_aes_crypt(struct geode_aes_op *op) +{ + + u32 flags = 0; + int iflags; + + if (op->len == 0 || op->src == op->dst) + return 0; + + if (op->flags & AES_FLAGS_COHERENT) + flags |= (AES_CTRL_DCA | AES_CTRL_SCA); + + if (op->dir == AES_DIR_ENCRYPT) + flags |= AES_CTRL_ENCRYPT; + + /* Start the critical section */ + + spin_lock_irqsave(&lock, iflags); + + if (op->mode == AES_MODE_CBC) { + flags |= AES_CTRL_CBC; + _writefield(AES_WRITEIV0_REG, op->iv); + } + + if (op->flags & AES_FLAGS_USRKEY) { + flags |= AES_CTRL_WRKEY; + _writefield(AES_WRITEKEY0_REG, op->key); + } + + do_crypt(op->src, op->dst, op->len, flags); + + if (op->mode == AES_MODE_CBC) + _readfield(AES_WRITEIV0_REG, op->iv); + + spin_unlock_irqrestore(&lock, iflags); + + return op->len; +} + +/* CRYPTO-API Functions */ + +static int +geode_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int len) +{ + struct geode_aes_op *op = crypto_tfm_ctx(tfm); + + if (len != AES_KEY_LENGTH) { + tfm->crt_flags |= CRYPTO_TFM_RES_BAD_KEY_LEN; + return -EINVAL; + } + + memcpy(op->key, key, len); + return 0; +} + +static void +geode_encrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +{ + struct geode_aes_op *op = crypto_tfm_ctx(tfm); + + if ((out == NULL) || (in == NULL)) + return; + + op->src = (void *) in; + op->dst = (void *) out; + op->mode = AES_MODE_ECB; + op->flags = 0; + op->len = AES_MIN_BLOCK_SIZE; + op->dir = AES_DIR_ENCRYPT; + + geode_aes_crypt(op); +} + + +static void +geode_decrypt(struct crypto_tfm *tfm, u8 *out, const u8 *in) +{ + struct geode_aes_op *op = crypto_tfm_ctx(tfm); + + if ((out == NULL) || (in == NULL)) + return; + + op->src = (void *) in; + op->dst = (void *) out; + op->mode = AES_MODE_ECB; + op->flags = 0; + op->len = AES_MIN_BLOCK_SIZE; + op->dir = AES_DIR_DECRYPT; + + geode_aes_crypt(op); +} + + +static struct crypto_alg geode_alg = { + .cra_name = "aes", + .cra_driver_name = "geode-aes-128", + .cra_priority = 300, + .cra_alignmask = 15, + .cra_flags = CRYPTO_ALG_TYPE_CIPHER, + .cra_blocksize = AES_MIN_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct geode_aes_op), + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(geode_alg.cra_list), + .cra_u = { + .cipher = { + .cia_min_keysize = AES_KEY_LENGTH, + .cia_max_keysize = AES_KEY_LENGTH, + .cia_setkey = geode_setkey, + .cia_encrypt = geode_encrypt, + .cia_decrypt = geode_decrypt + } + } +}; + +static int +geode_cbc_decrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{ + struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err, ret; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while((nbytes = walk.nbytes)) { + op->src = walk.src.virt.addr, + op->dst = walk.dst.virt.addr; + op->mode = AES_MODE_CBC; + op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE); + op->dir = AES_DIR_DECRYPT; + + memcpy(op->iv, walk.iv, AES_IV_LENGTH); + + ret = geode_aes_crypt(op); + + memcpy(walk.iv, op->iv, AES_IV_LENGTH); + nbytes -= ret; + + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + return err; +} + +static int +geode_cbc_encrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{ + struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err, ret; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while((nbytes = walk.nbytes)) { + op->src = walk.src.virt.addr, + op->dst = walk.dst.virt.addr; + op->mode = AES_MODE_CBC; + op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE); + op->dir = AES_DIR_ENCRYPT; + + memcpy(op->iv, walk.iv, AES_IV_LENGTH); + + ret = geode_aes_crypt(op); + nbytes -= ret; + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + return err; +} + +static struct crypto_alg geode_cbc_alg = { + .cra_name = "cbc(aes)", + .cra_driver_name = "cbc-aes-geode-128", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = AES_MIN_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct geode_aes_op), + .cra_alignmask = 15, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(geode_cbc_alg.cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = AES_KEY_LENGTH, + .max_keysize = AES_KEY_LENGTH, + .setkey = geode_setkey, + .encrypt = geode_cbc_encrypt, + .decrypt = geode_cbc_decrypt, + } + } +}; + +static int +geode_ecb_decrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{ + struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err, ret; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while((nbytes = walk.nbytes)) { + op->src = walk.src.virt.addr, + op->dst = walk.dst.virt.addr; + op->mode = AES_MODE_ECB; + op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE); + op->dir = AES_DIR_DECRYPT; + + ret = geode_aes_crypt(op); + nbytes -= ret; + err = blkcipher_walk_done(desc, &walk, nbytes); + } + + return err; +} + +static int +geode_ecb_encrypt(struct blkcipher_desc *desc, + struct scatterlist *dst, struct scatterlist *src, + unsigned int nbytes) +{ + struct geode_aes_op *op = crypto_blkcipher_ctx(desc->tfm); + struct blkcipher_walk walk; + int err, ret; + + blkcipher_walk_init(&walk, dst, src, nbytes); + err = blkcipher_walk_virt(desc, &walk); + + while((nbytes = walk.nbytes)) { + op->src = walk.src.virt.addr, + op->dst = walk.dst.virt.addr; + op->mode = AES_MODE_ECB; + op->len = nbytes - (nbytes % AES_MIN_BLOCK_SIZE); + op->dir = AES_DIR_ENCRYPT; + + ret = geode_aes_crypt(op); + nbytes -= ret; + ret = blkcipher_walk_done(desc, &walk, nbytes); + } + + return err; +} + +static struct crypto_alg geode_ecb_alg = { + .cra_name = "ecb(aes)", + .cra_driver_name = "ecb-aes-geode-128", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_BLKCIPHER, + .cra_blocksize = AES_MIN_BLOCK_SIZE, + .cra_ctxsize = sizeof(struct geode_aes_op), + .cra_alignmask = 15, + .cra_type = &crypto_blkcipher_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(geode_ecb_alg.cra_list), + .cra_u = { + .blkcipher = { + .min_keysize = AES_KEY_LENGTH, + .max_keysize = AES_KEY_LENGTH, + .setkey = geode_setkey, + .encrypt = geode_ecb_encrypt, + .decrypt = geode_ecb_decrypt, + } + } +}; + +static void +geode_aes_remove(struct pci_dev *dev) +{ + crypto_unregister_alg(&geode_alg); + crypto_unregister_alg(&geode_ecb_alg); + crypto_unregister_alg(&geode_cbc_alg); + + pci_iounmap(dev, _iobase); + _iobase = NULL; + + pci_release_regions(dev); + pci_disable_device(dev); +} + + +static int +geode_aes_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + int ret; + + if ((ret = pci_enable_device(dev))) + return ret; + + if ((ret = pci_request_regions(dev, "geode-aes-128"))) + goto eenable; + + _iobase = pci_iomap(dev, 0, 0); + + if (_iobase == NULL) { + ret = -ENOMEM; + goto erequest; + } + + spin_lock_init(&lock); + + /* Clear any pending activity */ + iowrite32(AES_INTR_PENDING | AES_INTR_MASK, _iobase + AES_INTR_REG); + + if ((ret = crypto_register_alg(&geode_alg))) + goto eiomap; + + if ((ret = crypto_register_alg(&geode_ecb_alg))) + goto ealg; + + if ((ret = crypto_register_alg(&geode_cbc_alg))) + goto eecb; + + printk(KERN_NOTICE "geode-aes: GEODE AES engine enabled.\n"); + return 0; + + eecb: + crypto_unregister_alg(&geode_ecb_alg); + + ealg: + crypto_unregister_alg(&geode_alg); + + eiomap: + pci_iounmap(dev, _iobase); + + erequest: + pci_release_regions(dev); + + eenable: + pci_disable_device(dev); + + printk(KERN_ERR "geode-aes: GEODE AES initialization failed.\n"); + return ret; +} + +static struct pci_device_id geode_aes_tbl[] = { + { PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LX_AES, PCI_ANY_ID, PCI_ANY_ID} , + { 0, } +}; + +MODULE_DEVICE_TABLE(pci, geode_aes_tbl); + +static struct pci_driver geode_aes_driver = { + .name = "Geode LX AES", + .id_table = geode_aes_tbl, + .probe = geode_aes_probe, + .remove = __devexit_p(geode_aes_remove) +}; + +static int __init +geode_aes_init(void) +{ + return pci_module_init(&geode_aes_driver); +} + +static void __exit +geode_aes_exit(void) +{ + pci_unregister_driver(&geode_aes_driver); +} + +MODULE_AUTHOR("Advanced Micro Devices, Inc."); +MODULE_DESCRIPTION("Geode LX Hardware AES driver"); +MODULE_LICENSE("GPL"); + +module_init(geode_aes_init); +module_exit(geode_aes_exit); diff --git a/drivers/crypto/geode-aes.h b/drivers/crypto/geode-aes.h new file mode 100644 index 000000000000..3e3a571d4a20 --- /dev/null +++ b/drivers/crypto/geode-aes.h @@ -0,0 +1,42 @@ +/* Copyright (C) 2003-2006, Advanced Micro Devices, Inc. + * + * 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 of the License, or + * (at your option) any later version. + */ + +#ifndef _GEODE_AES_H_ +#define _GEODE_AES_H_ + +#define AES_KEY_LENGTH 16 +#define AES_IV_LENGTH 16 + +#define AES_MIN_BLOCK_SIZE 16 + +#define AES_MODE_ECB 0 +#define AES_MODE_CBC 1 + +#define AES_DIR_DECRYPT 0 +#define AES_DIR_ENCRYPT 1 + +#define AES_FLAGS_USRKEY (1 << 0) +#define AES_FLAGS_COHERENT (1 << 1) + +struct geode_aes_op { + + void *src; + void *dst; + + u32 mode; + u32 dir; + u32 flags; + int len; + + u8 key[AES_KEY_LENGTH]; + u8 iv[AES_IV_LENGTH]; +}; + +unsigned int geode_aes_crypt(struct geode_aes_op *); + +#endif -- cgit v1.2.1 From 48527fa7cf7fefb84e9fe03cddd08ddafc9f15f3 Mon Sep 17 00:00:00 2001 From: Rik Snel Date: Sun, 3 Sep 2006 08:56:39 +1000 Subject: [BLOCK] dm-crypt: benbi IV, big endian narrow block count for LRW-32-AES LRW-32-AES needs a certain IV. This IV should be provided dm-crypt. The block cipher mode could, in principle generate the correct IV from the plain IV, but I think that it is cleaner to supply the right IV directly. The sector -> narrow block calculation uses a shift for performance reasons. This shift is computed in .ctr and stored in cc->iv_gen_private (as a void *). Signed-off-by: Rik Snel Signed-off-by: Herbert Xu --- drivers/md/dm-crypt.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index ed2d4ef27fd8..6dbaeee48ced 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "dm.h" @@ -113,6 +114,9 @@ static kmem_cache_t *_crypt_io_pool; * encrypted with the bulk cipher using a salt as key. The salt * should be derived from the bulk cipher's key via hashing. * + * benbi: the 64-bit "big-endian 'narrow block'-count", starting at 1 + * (needed for LRW-32-AES and possible other narrow block modes) + * * plumb: unimplemented, see: * http://article.gmane.org/gmane.linux.kernel.device-mapper.dm-crypt/454 */ @@ -209,6 +213,44 @@ static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector) return 0; } +static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti, + const char *opts) +{ + unsigned int bs = crypto_blkcipher_blocksize(cc->tfm); + int log = long_log2(bs); + + /* we need to calculate how far we must shift the sector count + * to get the cipher block count, we use this shift in _gen */ + + if (1 << log != bs) { + ti->error = "cypher blocksize is not a power of 2"; + return -EINVAL; + } + + if (log > 9) { + ti->error = "cypher blocksize is > 512"; + return -EINVAL; + } + + cc->iv_gen_private = (void *)(9 - log); + + return 0; +} + +static void crypt_iv_benbi_dtr(struct crypt_config *cc) +{ + cc->iv_gen_private = NULL; +} + +static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv, sector_t sector) +{ + memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */ + put_unaligned(cpu_to_be64(((u64)sector << (u32)cc->iv_gen_private) + 1), + (__be64 *)(iv + cc->iv_size - sizeof(u64))); + + return 0; +} + static struct crypt_iv_operations crypt_iv_plain_ops = { .generator = crypt_iv_plain_gen }; @@ -219,6 +261,11 @@ static struct crypt_iv_operations crypt_iv_essiv_ops = { .generator = crypt_iv_essiv_gen }; +static struct crypt_iv_operations crypt_iv_benbi_ops = { + .ctr = crypt_iv_benbi_ctr, + .dtr = crypt_iv_benbi_dtr, + .generator = crypt_iv_benbi_gen +}; static int crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out, @@ -768,7 +815,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) cc->tfm = tfm; /* - * Choose ivmode. Valid modes: "plain", "essiv:". + * Choose ivmode. Valid modes: "plain", "essiv:", "benbi". * See comments at iv code */ @@ -778,6 +825,8 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv) cc->iv_gen_ops = &crypt_iv_plain_ops; else if (strcmp(ivmode, "essiv") == 0) cc->iv_gen_ops = &crypt_iv_essiv_ops; + else if (strcmp(ivmode, "benbi") == 0) + cc->iv_gen_ops = &crypt_iv_benbi_ops; else { ti->error = "Invalid IV mode"; goto bad2; -- cgit v1.2.1 From 45789328e5aa2de96d4467e4445418364e5378d7 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 3 Sep 2006 08:58:41 +1000 Subject: [BLOCK] dm-crypt: Align IV to u64 for essiv This patch makes the IV u64-aligned since essiv does a u64 store to it. Signed-off-by: Herbert Xu --- drivers/md/dm-crypt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index 6dbaeee48ced..facf859b9b87 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -272,7 +272,7 @@ crypt_convert_scatterlist(struct crypt_config *cc, struct scatterlist *out, struct scatterlist *in, unsigned int length, int write, sector_t sector) { - u8 iv[cc->iv_size]; + u8 iv[cc->iv_size] __attribute__ ((aligned(__alignof__(u64)))); struct blkcipher_desc desc = { .tfm = cc->tfm, .info = iv, -- cgit v1.2.1 From ab7827059adbbcc3624afbc58880287eabf6d277 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 17 Nov 2006 13:43:55 +1100 Subject: [CRYPTO] geode: Make needlessly global geode_aes_crypt() static On Tue, Nov 14, 2006 at 01:41:25AM -0800, Andrew Morton wrote: >... > Changes since 2.6.19-rc5-mm2: >... > git-cryptodev.patch >... > git trees >... This patch makes the needlessly global geode_aes_crypt() static. Signed-off-by: Adrian Bunk Signed-off-by: Herbert Xu --- drivers/crypto/geode-aes.c | 2 +- drivers/crypto/geode-aes.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/crypto/geode-aes.c b/drivers/crypto/geode-aes.c index da2d35db8b48..43a68398656f 100644 --- a/drivers/crypto/geode-aes.c +++ b/drivers/crypto/geode-aes.c @@ -97,7 +97,7 @@ do_crypt(void *src, void *dst, int len, u32 flags) return counter ? 0 : 1; } -unsigned int +static unsigned int geode_aes_crypt(struct geode_aes_op *op) { diff --git a/drivers/crypto/geode-aes.h b/drivers/crypto/geode-aes.h index 3e3a571d4a20..8003a36f3a83 100644 --- a/drivers/crypto/geode-aes.h +++ b/drivers/crypto/geode-aes.h @@ -37,6 +37,4 @@ struct geode_aes_op { u8 iv[AES_IV_LENGTH]; }; -unsigned int geode_aes_crypt(struct geode_aes_op *); - #endif -- cgit v1.2.1 From 8df3b0a219967080d9dc4b604b5fecacb6967af0 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sat, 2 Dec 2006 14:36:03 +1100 Subject: [CRYPTO] cryptoloop: Select CRYPTO_CBC As CBC is the default chaining method for cryptoloop, we should select it from cryptoloop to ease the transition. Signed-off-by: Herbert Xu --- drivers/block/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 17dc22282e14..e00568e0952b 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -305,6 +305,7 @@ config BLK_DEV_LOOP config BLK_DEV_CRYPTOLOOP tristate "Cryptoloop Support" select CRYPTO + select CRYPTO_CBC depends on BLK_DEV_LOOP ---help--- Say Y here if you want to be able to use the ciphers that are -- cgit v1.2.1 From 79066ad32be5bb2edf16733aec36acf2af03fc99 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 5 Dec 2006 13:41:52 -0800 Subject: [CRYPTO] dm-crypt: Make iv_gen_private a union Rather than stuffing integers into pointers with casts, let's use a union. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- drivers/md/dm-crypt.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c index facf859b9b87..0d8686505e51 100644 --- a/drivers/md/dm-crypt.c +++ b/drivers/md/dm-crypt.c @@ -86,7 +86,10 @@ struct crypt_config { */ struct crypt_iv_operations *iv_gen_ops; char *iv_mode; - struct crypto_cipher *iv_gen_private; + union { + struct crypto_cipher *essiv_tfm; + int benbi_shift; + } iv_gen_private; sector_t iv_offset; unsigned int iv_size; @@ -195,21 +198,21 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti, } kfree(salt); - cc->iv_gen_private = essiv_tfm; + cc->iv_gen_private.essiv_tfm = essiv_tfm; return 0; } static void crypt_iv_essiv_dtr(struct crypt_config *cc) { - crypto_free_cipher(cc->iv_gen_private); - cc->iv_gen_private = NULL; + crypto_free_cipher(cc->iv_gen_private.essiv_tfm); + cc->iv_gen_private.essiv_tfm = NULL; } static int crypt_iv_essiv_gen(struct crypt_config *cc, u8 *iv, sector_t sector) { memset(iv, 0, cc->iv_size); *(u64 *)iv = cpu_to_le64(sector); - crypto_cipher_encrypt_one(cc->iv_gen_private, iv, iv); + crypto_cipher_encrypt_one(cc->iv_gen_private.essiv_tfm, iv, iv); return 0; } @@ -232,21 +235,23 @@ static int crypt_iv_benbi_ctr(struct crypt_config *cc, struct dm_target *ti, return -EINVAL; } - cc->iv_gen_private = (void *)(9 - log); + cc->iv_gen_private.benbi_shift = 9 - log; return 0; } static void crypt_iv_benbi_dtr(struct crypt_config *cc) { - cc->iv_gen_private = NULL; } static int crypt_iv_benbi_gen(struct crypt_config *cc, u8 *iv, sector_t sector) { + __be64 val; + memset(iv, 0, cc->iv_size - sizeof(u64)); /* rest is cleared below */ - put_unaligned(cpu_to_be64(((u64)sector << (u32)cc->iv_gen_private) + 1), - (__be64 *)(iv + cc->iv_size - sizeof(u64))); + + val = cpu_to_be64(((u64)sector << cc->iv_gen_private.benbi_shift) + 1); + put_unaligned(val, (__be64 *)(iv + cc->iv_size - sizeof(u64))); return 0; } -- cgit v1.2.1 From b259e7d250e15d45b3c8362917931aaff1c88d73 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Wed, 6 Dec 2006 20:07:59 -0800 Subject: [IrDA]: PXA FIR code device model conversion pxaficp_ir.c was not converted to the device model framework. Signed-off-by: Paul Sokolovsky Signed-off-by: Andrew Morton Signed-off-by: Samuel Ortiz Signed-off-by: David S. Miller --- drivers/net/irda/pxaficp_ir.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/pxaficp_ir.c b/drivers/net/irda/pxaficp_ir.c index f9a1c88a4283..9137e239fac2 100644 --- a/drivers/net/irda/pxaficp_ir.c +++ b/drivers/net/irda/pxaficp_ir.c @@ -704,9 +704,9 @@ static int pxa_irda_stop(struct net_device *dev) return 0; } -static int pxa_irda_suspend(struct device *_dev, pm_message_t state) +static int pxa_irda_suspend(struct platform_device *_dev, pm_message_t state) { - struct net_device *dev = dev_get_drvdata(_dev); + struct net_device *dev = platform_get_drvdata(_dev); struct pxa_irda *si; if (dev && netif_running(dev)) { @@ -718,9 +718,9 @@ static int pxa_irda_suspend(struct device *_dev, pm_message_t state) return 0; } -static int pxa_irda_resume(struct device *_dev) +static int pxa_irda_resume(struct platform_device *_dev) { - struct net_device *dev = dev_get_drvdata(_dev); + struct net_device *dev = platform_get_drvdata(_dev); struct pxa_irda *si; if (dev && netif_running(dev)) { @@ -746,9 +746,8 @@ static int pxa_irda_init_iobuf(iobuff_t *io, int size) return io->head ? 0 : -ENOMEM; } -static int pxa_irda_probe(struct device *_dev) +static int pxa_irda_probe(struct platform_device *pdev) { - struct platform_device *pdev = to_platform_device(_dev); struct net_device *dev; struct pxa_irda *si; unsigned int baudrate_mask; @@ -822,9 +821,9 @@ err_mem_1: return err; } -static int pxa_irda_remove(struct device *_dev) +static int pxa_irda_remove(struct platform_device *_dev) { - struct net_device *dev = dev_get_drvdata(_dev); + struct net_device *dev = platform_get_drvdata(_dev); if (dev) { struct pxa_irda *si = netdev_priv(dev); @@ -840,9 +839,10 @@ static int pxa_irda_remove(struct device *_dev) return 0; } -static struct device_driver pxa_ir_driver = { - .name = "pxa2xx-ir", - .bus = &platform_bus_type, +static struct platform_driver pxa_ir_driver = { + .driver = { + .name = "pxa2xx-ir", + }, .probe = pxa_irda_probe, .remove = pxa_irda_remove, .suspend = pxa_irda_suspend, @@ -851,12 +851,12 @@ static struct device_driver pxa_ir_driver = { static int __init pxa_irda_init(void) { - return driver_register(&pxa_ir_driver); + return platform_driver_register(&pxa_ir_driver); } static void __exit pxa_irda_exit(void) { - driver_unregister(&pxa_ir_driver); + platform_driver_unregister(&pxa_ir_driver); } module_init(pxa_irda_init); -- cgit v1.2.1 From 5d64ad34f468278ce66f9eb4d876dd221490e94c Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 7 Dec 2006 00:19:40 -0800 Subject: [TG3]: Fix Phy loopback. Phy loopback on most 10/100 devices need to be run in 1Gbps mode in GMII mode. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index d9123c9adc1e..e6561c1d85d6 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8781,17 +8781,20 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) tg3_writephy(tp, 0x10, phy & ~0x4000); tg3_writephy(tp, MII_TG3_EPHY_TEST, phytest); } - } - val = BMCR_LOOPBACK | BMCR_FULLDPLX; - if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) - val |= BMCR_SPEED100; - else - val |= BMCR_SPEED1000; + val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED100; + } else + val = BMCR_LOOPBACK | BMCR_FULLDPLX | BMCR_SPEED1000; tg3_writephy(tp, MII_BMCR, val); udelay(40); - if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) + + mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | + MAC_MODE_LINK_POLARITY; + if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { tg3_writephy(tp, MII_TG3_EPHY_PTEST, 0x1800); + mac_mode |= MAC_MODE_PORT_MODE_MII; + } else + mac_mode |= MAC_MODE_PORT_MODE_GMII; /* reset to prevent losing 1st rx packet intermittently */ if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { @@ -8799,12 +8802,6 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) udelay(10); tw32_f(MAC_RX_MODE, tp->rx_mode); } - mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | - MAC_MODE_LINK_POLARITY; - if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) - mac_mode |= MAC_MODE_PORT_MODE_MII; - else - mac_mode |= MAC_MODE_PORT_MODE_GMII; if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) { mac_mode &= ~MAC_MODE_LINK_POLARITY; tg3_writephy(tp, MII_TG3_EXT_CTRL, -- cgit v1.2.1 From 676917d488212303ce4a7d033815ce8799201010 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 7 Dec 2006 00:20:22 -0800 Subject: [TG3]: Add 5787F device ID. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index e6561c1d85d6..5514828b7929 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -192,6 +192,7 @@ static struct pci_device_id tg3_pci_tbl[] = { {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5786)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787M)}, + {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5787F)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714S)}, {PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715)}, @@ -10859,7 +10860,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->pdev->device == PCI_DEVICE_ID_TIGON3_5705F)) || (tp->pdev->vendor == PCI_VENDOR_ID_BROADCOM && (tp->pdev->device == PCI_DEVICE_ID_TIGON3_5751F || - tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F)) || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5753F || + tp->pdev->device == PCI_DEVICE_ID_TIGON3_5787F)) || GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) tp->tg3_flags |= TG3_FLAG_10_100_ONLY; -- cgit v1.2.1 From 9d26e213423923c9e033ccd373705118131827c9 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 7 Dec 2006 00:21:14 -0800 Subject: [TG3]: Add TG3_FLG2_IS_NIC flag. Add Tg3_FLG2_IS_NIC flag to unambiguously determine whether the device is NIC or onboard. Previously, the EEPROM_WRITE_PROT flag was overloaded to also mean onboard. With the separation, we can support some devices that are onboard but do not use eeprom write protect. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 37 ++++++++++++++++++++++++------------- drivers/net/tg3.h | 1 + 2 files changed, 25 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 5514828b7929..16bc05fe531f 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1062,7 +1062,7 @@ static void tg3_frob_aux_power(struct tg3 *tp) { struct tg3 *tp_peer = tp; - if ((tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) != 0) + if ((tp->tg3_flags2 & TG3_FLG2_IS_NIC) == 0) return; if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704) || @@ -1213,8 +1213,8 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) power_control); udelay(100); /* Delay after power state change */ - /* Switch out of Vaux if it is not a LOM */ - if (!(tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT)) + /* Switch out of Vaux if it is a NIC */ + if (tp->tg3_flags2 & TG3_FLG2_IS_NIC) tw32_wait_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl, 100); return 0; @@ -6397,16 +6397,17 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) udelay(40); /* tp->grc_local_ctrl is partially set up during tg3_get_invariants(). - * If TG3_FLAG_EEPROM_WRITE_PROT is set, we should read the + * If TG3_FLG2_IS_NIC is zero, we should read the * register to preserve the GPIO settings for LOMs. The GPIOs, * whether used as inputs or outputs, are set by boot code after * reset. */ - if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) { + if (!(tp->tg3_flags2 & TG3_FLG2_IS_NIC)) { u32 gpio_mask; - gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE2 | - GRC_LCLCTRL_GPIO_OUTPUT0 | GRC_LCLCTRL_GPIO_OUTPUT2; + gpio_mask = GRC_LCLCTRL_GPIO_OE0 | GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OE2 | GRC_LCLCTRL_GPIO_OUTPUT0 | + GRC_LCLCTRL_GPIO_OUTPUT1 | GRC_LCLCTRL_GPIO_OUTPUT2; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) gpio_mask |= GRC_LCLCTRL_GPIO_OE3 | @@ -6418,8 +6419,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) tp->grc_local_ctrl |= tr32(GRC_LOCAL_CTRL) & gpio_mask; /* GPIO1 must be driven high for eeprom write protect */ - tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | - GRC_LCLCTRL_GPIO_OUTPUT1); + if (tp->tg3_flags & TG3_FLAG_EEPROM_WRITE_PROT) + tp->grc_local_ctrl |= (GRC_LCLCTRL_GPIO_OE1 | + GRC_LCLCTRL_GPIO_OUTPUT1); } tw32_f(GRC_LOCAL_CTRL, tp->grc_local_ctrl); udelay(100); @@ -9963,8 +9965,10 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5906) { - if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) + if (!(tr32(PCIE_TRANSACTION_CFG) & PCIE_TRANS_CFG_LOM)) { tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; + tp->tg3_flags2 |= TG3_FLG2_IS_NIC; + } return; } @@ -10064,10 +10068,17 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) tp->pdev->subsystem_vendor == PCI_VENDOR_ID_DELL) tp->led_ctrl = LED_CTRL_MODE_PHY_2; - if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) + if (nic_cfg & NIC_SRAM_DATA_CFG_EEPROM_WP) { tp->tg3_flags |= TG3_FLAG_EEPROM_WRITE_PROT; - else + if ((tp->pdev->subsystem_vendor == + PCI_VENDOR_ID_ARIMA) && + (tp->pdev->subsystem_device == 0x205a || + tp->pdev->subsystem_device == 0x2063)) + tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; + } else { tp->tg3_flags &= ~TG3_FLAG_EEPROM_WRITE_PROT; + tp->tg3_flags2 |= TG3_FLG2_IS_NIC; + } if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; @@ -10693,7 +10704,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) tp->tg3_flags |= TG3_FLAG_SRAM_USE_CONFIG; /* Get eeprom hw config before calling tg3_set_power_state(). - * In particular, the TG3_FLAG_EEPROM_WRITE_PROT flag must be + * In particular, the TG3_FLG2_IS_NIC flag must be * determined before calling tg3_set_power_state() so that * we know whether or not to switch out of Vaux power. * When the flag is set, it means that GPIO1 is used for eeprom diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 92f53000bce6..dfaf4ed127bd 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h @@ -2233,6 +2233,7 @@ struct tg3 { #define TG3_FLG2_PCI_EXPRESS 0x00000200 #define TG3_FLG2_ASF_NEW_HANDSHAKE 0x00000400 #define TG3_FLG2_HW_AUTONEG 0x00000800 +#define TG3_FLG2_IS_NIC 0x00001000 #define TG3_FLG2_PHY_SERDES 0x00002000 #define TG3_FLG2_CAPACITIVE_COUPLING 0x00004000 #define TG3_FLG2_FLASH 0x00008000 -- cgit v1.2.1 From 3600d918d870456ea8e7bb9d47f327de5c20f3d6 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 7 Dec 2006 00:21:48 -0800 Subject: [TG3]: Allow partial speed advertisement. Honor the advertisement bitmask from ethtool. We used to always advertise the full capability when autoneg was set to on. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 16bc05fe531f..576e9ea0a566 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1558,12 +1558,6 @@ static void tg3_phy_copper_begin(struct tg3 *tp) tg3_writephy(tp, MII_ADVERTISE, new_adv); } else if (tp->link_config.speed == SPEED_INVALID) { - tp->link_config.advertising = - (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | - ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | - ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full | - ADVERTISED_Autoneg | ADVERTISED_MII); - if (tp->tg3_flags & TG3_FLAG_10_100_ONLY) tp->link_config.advertising &= ~(ADVERTISED_1000baseT_Half | @@ -1707,25 +1701,36 @@ static int tg3_init_5401phy_dsp(struct tg3 *tp) return err; } -static int tg3_copper_is_advertising_all(struct tg3 *tp) +static int tg3_copper_is_advertising_all(struct tg3 *tp, u32 mask) { - u32 adv_reg, all_mask; + u32 adv_reg, all_mask = 0; + + if (mask & ADVERTISED_10baseT_Half) + all_mask |= ADVERTISE_10HALF; + if (mask & ADVERTISED_10baseT_Full) + all_mask |= ADVERTISE_10FULL; + if (mask & ADVERTISED_100baseT_Half) + all_mask |= ADVERTISE_100HALF; + if (mask & ADVERTISED_100baseT_Full) + all_mask |= ADVERTISE_100FULL; if (tg3_readphy(tp, MII_ADVERTISE, &adv_reg)) return 0; - all_mask = (ADVERTISE_10HALF | ADVERTISE_10FULL | - ADVERTISE_100HALF | ADVERTISE_100FULL); if ((adv_reg & all_mask) != all_mask) return 0; if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) { u32 tg3_ctrl; + all_mask = 0; + if (mask & ADVERTISED_1000baseT_Half) + all_mask |= ADVERTISE_1000HALF; + if (mask & ADVERTISED_1000baseT_Full) + all_mask |= ADVERTISE_1000FULL; + if (tg3_readphy(tp, MII_TG3_CTRL, &tg3_ctrl)) return 0; - all_mask = (MII_TG3_CTRL_ADV_1000_HALF | - MII_TG3_CTRL_ADV_1000_FULL); if ((tg3_ctrl & all_mask) != all_mask) return 0; } @@ -1885,7 +1890,8 @@ static int tg3_setup_copper_phy(struct tg3 *tp, int force_reset) /* Force autoneg restart if we are exiting * low power mode. */ - if (!tg3_copper_is_advertising_all(tp)) + if (!tg3_copper_is_advertising_all(tp, + tp->link_config.advertising)) current_link_up = 0; } else { current_link_up = 0; @@ -10156,7 +10162,7 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) && !(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { - u32 bmsr, adv_reg, tg3_ctrl; + u32 bmsr, adv_reg, tg3_ctrl, mask; tg3_readphy(tp, MII_BMSR, &bmsr); if (!tg3_readphy(tp, MII_BMSR, &bmsr) && @@ -10180,7 +10186,10 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) MII_TG3_CTRL_ENABLE_AS_MASTER); } - if (!tg3_copper_is_advertising_all(tp)) { + mask = (ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full | + ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full | + ADVERTISED_1000baseT_Half | ADVERTISED_1000baseT_Full); + if (!tg3_copper_is_advertising_all(tp, mask)) { tg3_writephy(tp, MII_ADVERTISE, adv_reg); if (!(tp->tg3_flags & TG3_FLAG_10_100_ONLY)) -- cgit v1.2.1 From 9f88f29fc502192824aba092e90af1297a87eb82 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 7 Dec 2006 00:22:54 -0800 Subject: [TG3]: Use netif_msg_*. Use netif_msg_* to turn on or off some messages. Based on Stephen Hemminger's initial patch. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 576e9ea0a566..0b50f1fc4e63 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -1402,8 +1402,10 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) static void tg3_link_report(struct tg3 *tp) { if (!netif_carrier_ok(tp->dev)) { - printk(KERN_INFO PFX "%s: Link is down.\n", tp->dev->name); - } else { + if (netif_msg_link(tp)) + printk(KERN_INFO PFX "%s: Link is down.\n", + tp->dev->name); + } else if (netif_msg_link(tp)) { printk(KERN_INFO PFX "%s: Link is up at %d Mbps, %s duplex.\n", tp->dev->name, (tp->link_config.active_speed == SPEED_1000 ? @@ -3710,8 +3712,9 @@ static void tg3_tx_timeout(struct net_device *dev) { struct tg3 *tp = netdev_priv(dev); - printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", - dev->name); + if (netif_msg_tx_err(tp)) + printk(KERN_ERR PFX "%s: transmit timed out, resetting\n", + dev->name); schedule_work(&tp->reset_task); } @@ -8665,7 +8668,9 @@ static int tg3_test_registers(struct tg3 *tp) return 0; out: - printk(KERN_ERR PFX "Register test failed at offset %x\n", offset); + if (netif_msg_hw(tp)) + printk(KERN_ERR PFX "Register test failed at offset %x\n", + offset); tw32(offset, save_val); return -EIO; } -- cgit v1.2.1 From 9d57f01c1331cb7bfd0a9d4f7723da5b9329394f Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 7 Dec 2006 00:23:25 -0800 Subject: [TG3]: Use msleep. Change some udelay() in some eeprom functions to msleep(). Eeprom related functions are always called from sleepable context. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 0b50f1fc4e63..cfb9098c800a 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -9467,16 +9467,12 @@ static void __devinit tg3_get_5906_nvram_info(struct tg3 *tp) /* Chips other than 5700/5701 use the NVRAM for fetching info. */ static void __devinit tg3_nvram_init(struct tg3 *tp) { - int j; - tw32_f(GRC_EEPROM_ADDR, (EEPROM_ADDR_FSM_RESET | (EEPROM_DEFAULT_CLOCK_PERIOD << EEPROM_ADDR_CLKPERD_SHIFT))); - /* XXX schedule_timeout() ... */ - for (j = 0; j < 100; j++) - udelay(10); + msleep(1); /* Enable seeprom accesses. */ tw32_f(GRC_LOCAL_CTRL, @@ -9537,12 +9533,12 @@ static int tg3_nvram_read_using_eeprom(struct tg3 *tp, EEPROM_ADDR_ADDR_MASK) | EEPROM_ADDR_READ | EEPROM_ADDR_START); - for (i = 0; i < 10000; i++) { + for (i = 0; i < 1000; i++) { tmp = tr32(GRC_EEPROM_ADDR); if (tmp & EEPROM_ADDR_COMPLETE) break; - udelay(100); + msleep(1); } if (!(tmp & EEPROM_ADDR_COMPLETE)) return -EBUSY; @@ -9667,12 +9663,12 @@ static int tg3_nvram_write_block_using_eeprom(struct tg3 *tp, EEPROM_ADDR_START | EEPROM_ADDR_WRITE); - for (j = 0; j < 10000; j++) { + for (j = 0; j < 1000; j++) { val = tr32(GRC_EEPROM_ADDR); if (val & EEPROM_ADDR_COMPLETE) break; - udelay(100); + msleep(1); } if (!(val & EEPROM_ADDR_COMPLETE)) { rc = -EBUSY; -- cgit v1.2.1 From cbb45d21fb2fcbcafc19ea859350f564252a0878 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Thu, 7 Dec 2006 00:24:09 -0800 Subject: [TG3]: Identify Serdes devices more clearly. Change the message to more clearly identify Serdes devices. Update version to 3.70. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index cfb9098c800a..571320ae87ab 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.69" -#define DRV_MODULE_RELDATE "November 15, 2006" +#define DRV_MODULE_VERSION "3.70" +#define DRV_MODULE_RELDATE "December 1, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -11932,13 +11932,15 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, pci_set_drvdata(pdev, dev); - printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %sBaseT Ethernet ", + printk(KERN_INFO "%s: Tigon3 [partno(%s) rev %04x PHY(%s)] (%s) %s Ethernet ", dev->name, tp->board_part_number, tp->pci_chip_rev_id, tg3_phy_string(tp), tg3_bus_string(tp, str), - (tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100" : "10/100/1000"); + ((tp->tg3_flags & TG3_FLAG_10_100_ONLY) ? "10/100Base-TX" : + ((tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) ? "1000Base-SX" : + "10/100/1000Base-T"))); for (i = 0; i < 6; i++) printk("%2.2x%c", dev->dev_addr[i], -- cgit v1.2.1